如何对已经登录成功的用户实现访问授权,也就是说,只有登录过的用户(有token值)才能访问特定的数据,该DRF的认证组件出场了。
DRF认证组件的使用方式 首先创建认证类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class UserAuth : def authenticate_header (self, request ): pass def authenticate (self, request ): try : token = request.GET.get('token' ) token_obj = UserTokenModel.objects.filter (token=token).first() if token_obj is not None : return token_obj.user.name, token else : raise APIException('Token无效' ) except Exception as err: raise APIException(err)
其次在需认证接口中指定认证类 1 2 3 4 5 6 class BooksView (ModelViewSet ): queryset = BookModel.objects.all () serializer_class = BookSerialize authentication_classes = [UserAuth]
DRF全局认证组件的使用方式 创建自定义认证类 该类位置为:app.untils.authentication.UserAuth
,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 from rest_framework.authentication import BaseAuthenticationfrom rest_framework.exceptions import APIExceptionfrom app.models import UserToken as UserTokenModelclass UserAuth (BaseAuthentication ): def authenticate (self, request ): try : token = request.GET.get('token' ) token_obj = UserTokenModel.objects.filter (token=token).first() if token_obj is not None : return token_obj.user, token raise APIException('token无效' ) except Exception: raise APIException('认证失败' )
修改setting文件 setting中添加以下代码,多个认证类在DEFAULT_AUTHENTICATION_CLASSES
列表中依次添加,且多个认证类如需返回数据只能在最后一个认证类中返回,否则后面的认证类将不再执行。
1 2 3 REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES' : ['app.untils.authentication.UserAuth' ] }
最后整个views代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 from django.http import JsonResponsefrom rest_framework.views import APIViewfrom rest_framework.viewsets import ModelViewSetfrom app.models import User as UserModelfrom app.models import UserToken as UserTokenModelfrom app.models import Book as BookModelfrom app.untils import get_tokenfrom app.api_serialize import BookSerializeclass UserView (APIView ): def post (self, request ): response = dict () recev_data = {'username' , 'password' } if recev_data.issubset(set (request.data)): userInfo = dict () for item in recev_data: userInfo[item] = request.data.get(item) user_obj = UserModel.objects.filter (**userInfo).first() if user_obj: access_token = get_token.generater_token() UserTokenModel.objects.update_or_create(user=user_obj, defaults={ 'token' :access_token }) response['status_code' ] = 200 response['status_message' ] = '恭喜你,登录成功' response['access_token' ] = access_token response['user_role' ] = user_obj.get_level_display() else : response['status_code' ] = 201 response['status_message' ] = '用户名或密码错误' return JsonResponse(response) class BooksView (ModelViewSet ): queryset = BookModel.objects.all () serializer_class = BookSerialize