【问题标题】:CSRF Exempt Failure - APIView csrf django rest frameworkCSRF Exempt Failure - APIView csrf django rest framework
【发布时间】:2013-05-06 06:57:15
【问题描述】:

我有以下代码:

问题是当我尝试访问用户登录/时出现错误: “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

【问题讨论】:

    标签: python django django-rest-framework


    【解决方案1】:

    我假设您使用 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("/")
    

    【讨论】:

      【解决方案2】:

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

      from rest_framework.authentication import SessionAuthentication as OriginalSessionAuthentication
      
      class SessionAuthentication(OriginalSessionAuthentication):
          def enforce_csrf(self, request):
              return
      

      【讨论】:

        【解决方案3】:

        解决这个问题的最简单方法:

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

        基本认证

        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({})
        

        【讨论】:

          【解决方案4】:

          让 enforce_csrf 检查什么都不做可能更好:

          from rest_framework.authentication import SessionAuthentication
          
          class UnsafeSessionAuthentication(SessionAuthentication):
          
              def enforce_csrf(self, *args, **kwargs):
                  '''
                  Bypass the CSRF checks altogether
                  '''
                  pass
          

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

          【讨论】:

            猜你喜欢
            • 2015-11-30
            • 2013-05-12
            • 1970-01-01
            • 2021-11-27
            • 2017-12-06
            • 1970-01-01
            • 1970-01-01
            • 2019-09-15
            • 2023-04-09
            相关资源
            最近更新 更多