我有以下代码:
问题是当我尝试访问用户登录时/我收到错误: “CSRF失败:未设置CSRF cookie。”
我该怎么办?
我正在使用django rest框架。
urls.py:
url(r'^user-login/$',
csrf_exempt(LoginView.as_view()),
name='user-login'),
views.py:
class LoginView(APIView):
"""
List all snippets, or create a new snippet.
"""
def get(self, request, format=None):
startups = Startup.objects.all()
serializer = StartupSerializer(startups, many=True)
return Response(serializer.data)
def post(self, request, format=None):
profile = request.POST
if ('user_name' not in profile or 'email_address' not in profile or 'oauth_secret' not in profile):
return Response(
{'error': 'No data'},
status=status.HTTP_400_BAD_REQUEST)
username = 'l' + profile['user_name']
email_address = profile['email_address']
oauth_secret = profile['oauth_secret']
password = oauth_secret
答案 0 :(得分:14)
我假设您使用django rest框架SessionBackend。这个后端执行implicit CSRF check
你可以通过以下方式避免这种情况:
from rest_framework.authentication import SessionAuthentication
class UnsafeSessionAuthentication(SessionAuthentication):
def authenticate(self, request):
http_request = request._request
user = getattr(http_request, 'user', None)
if not user or not user.is_active:
return None
return (user, None)
并在视图中将其设置为authentication_classes
class UnsafeLogin(APIView):
permission_classes = (AllowAny,) #maybe not needed in your case
authentication_classes = (UnsafeSessionAuthentication,)
def post(self, request, *args, **kwargs):
username = request.DATA.get("u");
password = request.DATA.get("p");
user = authenticate(username=username, password=password)
if user is not None:
login(request, user)
return redirect("/")
答案 1 :(得分:10)
实际上,在SessionAuthentication中禁用csrf检查的更好方法是:
from rest_framework.authentication import SessionAuthentication as OriginalSessionAuthentication
class SessionAuthentication(OriginalSessionAuthentication):
def enforce_csrf(self, request):
return
答案 2 :(得分:2)
解决此问题的最简单方法:
为此,drf see drf auth
中有两种身份验证方式BasicAuthentication
SessionAuthentication(默认)
SessionAuthentication有强制csrf检查,但BasicAuthentication没有。 所以我的方法是在我的视图中使用BasicAuthentication而不是SessionAuthentication。
from rest_framework.authentication import BasicAuthentication
class UserLogin(generics.CreateAPIView):
permission_classes = (permissions.AllowAny,)
serializer_class = UserSerializer
authentication_classes = (BasicAuthentication,)
def post(self, request, *args, **kwargs):
return Response({})
答案 3 :(得分:0)
最好只执行一下execute_csrf检查:
from rest_framework.authentication import SessionAuthentication
class UnsafeSessionAuthentication(SessionAuthentication):
def enforce_csrf(self, *args, **kwargs):
'''
Bypass the CSRF checks altogether
'''
pass
否则,如果上游authenticate()方法发生更改,您将来可能会遇到问题。另外,仅使检查不执行任何操作是非常简单的:-)