9

我有以下代码:

问题是当我尝试访问用户登录/我收到错误:“CSRF 失败:未设置 CSRF cookie。”

我能做些什么?

我正在使用 django 休息框架。

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
4

4 回答 4

14

我假设您使用 django 休息框架SessionBackend。此后端执行隐式 CSRF 检查

您可以通过以下方式避免这种情况:

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("/")
于 2013-07-02T11:12:49.487 回答
13

实际上,在 SessionAuthentication 中禁用 csrf 检查的更好方法是:

from rest_framework.authentication import SessionAuthentication as OriginalSessionAuthentication

class SessionAuthentication(OriginalSessionAuthentication):
    def enforce_csrf(self, request):
        return
于 2015-02-03T13:45:36.180 回答
2

解决此问题的最简单方法:

为此,在 drf 中有两种身份验证方式,请参见 drf auth

基本认证

会话身份验证(默认)

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({})
于 2015-10-17T18:12:48.253 回答
0

最好让 enforce_csrf 检查什么都不做:

from rest_framework.authentication import SessionAuthentication

class UnsafeSessionAuthentication(SessionAuthentication):

    def enforce_csrf(self, *args, **kwargs):
        '''
        Bypass the CSRF checks altogether
        '''
        pass

否则,如果上游 authenticate() 方法发生更改,您将来可能会遇到问题。此外,让检查不做任何事情要简单得多:-)

于 2019-12-02T15:12:36.983 回答