Django-Rest-Fram中令牌认证的实现

2024-04-27 03:43:25 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用Django Rest框架开发一个API后端。我最初是使用会话身份验证开发它的,不知道它不能用于发送到移动应用程序。我在尝试用户在Postman中登录时遇到有关CSRF保护的问题。在

现在,既然我必须转换到基于令牌的身份验证来实现它,那么我该如何实现呢?我想知道如何快速实施。我已经浏览了stackoverflow的教程和答案,但无法在实践中实现这一点

另外,令牌身份验证是最适合身份验证的方法吗?我应该使用默认提供的DRF模块、JWT或其他实现吗?我可以简单地将令牌身份验证用于用户登录,而将会话身份验证用于其他3个api吗?在

class UserLogin(APIView):
queryset = User.objects.all()
serializer_class = UserSerializer
def post(self, request, format='json'):
    username = request.POST.get('username')
    email = request.POST.get('email')
    password = request.POST.get('password')
    user = EmailBackend.authenticate(self,username = email, password = password)
    if user:
        id = user.id
        return Response(id, status=status.HTTP_201_CREATED)
    else:
        return Response("Failure", status=HTTP_400_BAD_REQUEST)

class UserRegistration(APIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    def post(self, request, format='json'):
        serializer = UserSerializer(data=request.data)
        if serializer.is_valid():
             user = serializer.save()
             if user:
             return Response('Success', status=status.HTTP_201_CREATED)
        else:
            return Response(serializer.errors, status=HTTP_400_BAD_REQUEST)

class RecommendationQuestions(generics.ListCreateAPIView):
    def post(self, request, format = 'json'):
        """Save the post data when logging in."""
        uid = request.data['user_id']
        resp_list = MovieSerializer.provide_movie_choices(uid)
        return Response(resp_list, status=status.HTTP_400_BAD_REQUEST)

class RecommendationGenerator(generics.ListCreateAPIView):
    queryset = Ratings.objects.all()#.filter(id__in=(1,2))
    serializer_class= RatingsSerializer#(queryset,many=True)
    def post(self, request, format='json'):
        many = isinstance(request.data, list)
        serializer = RatingsSerializer(data = request.data, many = many)
        x = 0
        if serializer.is_valid():
            uid = [d['userId'] for d in serializer.data]
            resp_list = RatingsSerializer.generate_recommendations(self, uid[0])
            return Response(resp_list, status=status.HTTP_201_CREATED)
        else:
            return Response(serializer.errors,status=status.HTTP_400_BAD_REQUEST)

这是视图.py对于API。在


Tags: self身份验证idhttpdatareturnresponserequest
2条回答

令牌身份验证设置

您可以通过包括

'rest_framework.authtoken'

在已安装的应用程序设置(documentation)中。在

之后必须运行migrate。运行迁移后,需要为用户创建令牌。下面是一个执行此操作的示例代码:

^{pr2}$

你只运行一次。另外,您需要为每个新用户创建令牌。您可以使用post_save信号自动执行此操作:

from django.contrib.auth.models import User
from django.dispatch import receiver
from django.db.models.signals import post_save
from rest_framework.authtoken.models import Token

@receiver(post_save, sender=User)
def create_auth_token(sender, instance=None, created=False, **kwargs):
    if created:
        Token.objects.create(user=instance) 

此外,您还必须添加configure身份验证类,方法是包括

'rest_framework.authentication.TokenAuthentication'

在您的设置中'DEFAULT_AUTHENTICATION_CLASSES'documentation

您需要做的最后一件事是将令牌身份验证的url添加到您的urls.py

from rest_framework.authtoken import views as drf_views

urlpatterns += [
    path('api-token-auth/', drf_views.obtain_auth_token)
]

基于会话的身份验证用于使用浏览器登录到API。基于令牌的身份验证是无状态的,这意味着服务器不会在服务器上存储任何有关客户端会话的状态。阅读更多关于区别here。如果您通过基于令牌的身份验证登录,您将不会有会话,也将无法通过令牌以任何其他方式访问API。在

身份验证示例

下面是Python中使用requests库进行令牌身份验证的示例代码。在

# Authentication
import requests
r = requests.post(<add your token auth url here>, data={'username': 'my_username', 'password': 'my_password'})
if r.status_code == 200:
    response = r.json()
    token = response['token']
    print(token)

令牌必须用于每个其他API请求。它是通过邮件头发送的。在

# Consume API
import requests
headers = {'Authorization': 'Token {}'.format(<your token here>)}
# Request method is either GET, POST, PUT, PATCH or DELETE
r = requests.request(method=<request method>, url=<url to api>, headers=headers)

# or you can also use
# requests.get(url=<url to api>, headers=headers) or
# requests.post(url=<url to api>, headers=headers, data=<your data>) etc.

我建议你使用JWT,它比其他什么安全得多_framework.authtoken提供了一对令牌/刷新令牌,以便为主令牌设置较小的过期时间。这减少了代币被盗或损坏的机会。也可以在JWT令牌中存储负载,这在很多情况下非常有用。在

有一个非常好的DRF库,它实现了将JWT与DRF结合使用的所有方面,它非常灵活,可以适应您的目的。在

http://getblimp.github.io/django-rest-framework-jwt/

Could I use token authentication simply for user login, and session authentication for the other 3 APIs?

是的,你绝对可以。每个APIView实例都有属性“authentication_classes”,您可以专门为所需的api设置SessionAuthentication。在

例如:

class RecommendationQuestions(generics.ListCreateAPIView):
        authentication_classes = (SessionAuthentication, )

        def post(self, request, format = 'json'):
            """Save the post data when logging in."""
            uid = request.data['user_id']
            resp_list = MovieSerializer.provide_movie_choices(uid)
            return Response(resp_list, status=status.HTTP_400_BAD_REQUEST)

或者你可以两者兼用

^{pr2}$

相关问题 更多 >