首先token認證環境搭建:
安裝模塊:pip install djangorestframework
在settings中添加參數:
如圖:
繼續添加REST_FRAMEWORK項:
如圖:
配置如下:
REST_FRAMEWORK = { # 權限驗證,全局配置 "DEFAULT_PERMISSION_CLASSES":( 'rest_framework.permissions.AllowAny', # 允許所有用戶 # 'rest_framework.permissions.IsAdminUser', # 管理員用戶 # 'rest_framework.permissions.IsAuthenticatedOrReadOnly', #'rest_framework.permissions.IsAuthenticated', ), # 身份認證 "DEFAULT_AUTHENTICATION_CLASSES":( 'rest_framework.authentication.BasicAuthentication', 'rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.TokenAuthentication', # token認證 ) }
同步數據庫生成authtoken_token表:
編寫登錄視圖函數,登錄成功產生token:
from django.contrib.auth import authenticate, login from rest_framework.authtoken.models import Token from rest_framework.permissions import AllowAny,IsAuthenticated from django.http import HttpResponse, JsonResponse, HttpResponseRedirect class LoginViewSet(APIView): permission_classes = (AllowAny,) #todo 登錄允許每個人訪問,元祖要加逗號 def post(self, request, *args, **kwargs): username = request.data.get('username') password = request.data.get('password') user = authenticate(username=username, password=password) if not user: result = {"code": 1, "msg": "用戶名或密碼錯誤"} return JsonResponse(result) else: # 先刪除原有token oid_token = Token.objects.filter(user=user) oid_token.delete() # 創建新的token token = Token.objects.create(user=user) result = {"code": 0, "msg": "login success!", "username": user.username, "token": token.key } return JsonResponse(result)
配置urls訪問地址:
接口訪問如圖:
Permission權限驗證:
Token,只有通過接口權限驗證的才能訪問:
如下:用戶訪問只有帶上登錄成功產生的token才能訪問
from rest_framework.authentication import TokenAuthentication from django.http import HttpResponse, JsonResponse class CardListAPIView(APIView): '''rest_framework序列化''' authentication_classes = (TokenAuthentication,) # token認證方式 permission_classes = (IsAuthenticated,) # 登錄用戶才能訪問這個接口 def get(self, request, format=None): cards = Card.objects.all() serializer = CardAPISerializer(cards, many=True) result = { "code": 0, "msg": "success!", "data": serializer.data } return Response(result) def post(self, request, format=None): '''反序列化''' verify_data = CardAPISerializer(data=request.data) if verify_data.is_valid(): # 如果數據是合法,就報存 verify_data.save() result = { "code": 0, "msg": "success!", "data": request.data } return Response(result)
配置訪問地址:
接口帶上token訪問如圖:
接口沒帶token,訪問報錯401:
設置接口權限為管理員用戶才能訪問,普通用戶訪問接口報錯403:
總結:
401和403的區別:
401是登錄認證失敗,返回401
403是權限驗證失敗,返回403