CSRF豁免失败 - APIView CSRF Django的REST框架(CSRF Exempt

2019-09-02 15:40发布

我有以下代码:

问题是,当我试图访问用户登录/我得到一个错误:“CSRF失败:未设置CSRF饼干。”

我能做什么?

我使用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

Answer 1:

我假设你使用Django的REST框架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("/")


Answer 2:

其实,更好的方法来禁用CSRF检查里面SessionAuthentication是:

from rest_framework.authentication import SessionAuthentication as OriginalSessionAuthentication

class SessionAuthentication(OriginalSessionAuthentication):
    def enforce_csrf(self, request):
        return


Answer 3:

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

对于有在DRF认证的两种方式见DRF AUTH

BasicAuthentication

SessionAuthentication(默认)

SessionAuthentication具有强制CSRF检查,但BasicAuthentication没有。 所以我的方式在我看来不是SessionAuthentication使用BasicAuthentication。

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


文章来源: CSRF Exempt Failure - APIView csrf django rest framework