使用 simpleJWT 和 DjangoRestFramework 进行 CSRF 检查

问题描述 投票:0回答:2

我开始使用 django,但我迷失在请求验证系统中。我发现很难掌握身份验证方法的复杂性。

我正在使用 JWT 身份验证和restframework_simplejwt 来对用户进行身份验证。

在使用 JWT 之前,我进行了 CSRF 检查,但在我看来,自从我定义了这个身份验证系统后,我就不再进行这些检查了。

这是我的设置和我的视图,使用 DRF 的 ApiView 构建。

设置.py

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated'
    ],
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    ),
}

view.py

from rest_framework import status
from rest_framework.views import APIView
from rest_framework.permissions import IsAuthenticated
from rest_framework.authentication import SessionAuthentication
from rest_framework_simplejwt.authentication import JWTAuthentication
from rest_framework.response import Response

class MakePredictionView(APIView):
    authentication_classes = [JWTAuthentication,]
    permission_classes = [IsAuthenticated, UserPermissionSpeedX]
    throttle_classes = [UserThrottleSpeedX,]
    serializer_class = MakePredictionSerializer

    def post(self, request):
        if not self.request.session.exists(self.request.session.session_key):
            self.request.session.create()
        
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            profil = SpeedX(
                player_name=serializer.data.get('player_name'),
                maturite_indice=serializer.data.get('maturite_indice'),
                resultat_vitesse_30m=serializer.data.get('resultat_vitesse_30m'),
                club=serializer.data.get('club'),
                categorie=serializer.data.get('categorie')
            )
            profil.save()
            return Response(SpeedxSerializer(profil).data, status=status.HTTP_200_OK)

例如,如果我将 JWTAuthentification 替换为 SessionAuthentification,它会要求我提供 CSRF 令牌。但是,如果我在authentication_class中添加SessionAuthentification with JWTAuthentication,它就不再要求我提供CSRF,并且身份验证是使用JWT完成的,而不检查CSRF令牌。这是正常的吗?这有风险吗?

我也测试了这些参数,但同样的问题

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated'
    ],
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_simplejwt.authentication.JWTAuthentication',
        'rest_framework.authentication.SessionAuthentication'
    ),
}
class MakePredictionView(APIView):
    authentication_classes = [SessionAuthentication, JWTAuthentication]
    permission_classes = [IsAuthenticated, UserPermissionSpeedX]
    throttle_classes = [UserThrottleSpeedX,]
    serializer_class = MakePredictionSerializer

我不太明白什么时候检查 CSRF 令牌?为什么启用 JWTAuthentication 时不检查?

我目前正在本地开发应用程序。

django authentication django-rest-framework django-authentication django-rest-framework-simplejwt
2个回答
2
投票

Seesion 认证和 JWT 认证都用于用户认证,但区别在于:

会话认证

它是服务器端会话管理,用于跟踪用户的登录状态。当用户登录时,服务器创建一个包含用户会话 ID 的会话对象,该会话 ID 存储在 cookie 中。当用户请求时,服务器使用此会话 ID 来检索会话对象并对用户进行身份验证。

JWT 认证:

JWT 方法使用 Json Web 令牌来验证用户身份。当使用登录时,JWT 针对用户创建 JSON Web 令牌,并将其存储在 cokkie 或本地存储中。当用户请求时,客户端发送包含该使用的附加信息的令牌,并对用户进行身份验证并验证该用户。

主要优点是,JWT 身份验证比会话身份验证更灵活。


0
投票

如果您使用简单的 JWT 或任何形式的 JWT 身份验证,我建议您使用自定义方式来确保在执行任何操作之前验证 CSRF。在调用任何 POST,PUT 之前

此外,将 JWT 放在 localStorage 中不是一个好主意,您应该使用相同站点的 Cookie

您可以这样做:

def ensure_csrf(request):
"""
This function ensure csrf is validated manually. This is used for class based views
:param request:
:return:
"""
request.csrf_processing_done = False
reason = CsrfViewMiddleware(request).process_view(request, None, (), {})
if reason is not None:
    return reason
© www.soinside.com 2019 - 2024. All rights reserved.