jwt简单例子
一、登陆设置
1.不需要写login的视图类,使用jwt内置的。
2.需要前置条件,已有继承AbstractUser models,并且有数据,用于校验,返回token。
urls.py
from rest_framework_jwt.views import obtain_jwt_tokenurlpatterns = [path('login/', obtain_jwt_token),...
]
二、访问视图类设置
需要两者搭配,才能校验
authentication_classes = [JSONWebTokenAuthentication,]# 权限控制permission_classes = [IsAuthenticated,]
urls.py
urlpatterns = [path('login/', obtain_jwt_token),path('orderview/', views.OrderAPIView.as_view()),path('userinfo/', views.UserInfoAPIView.as_view()),]
views.py
from rest_framework.views import APIView
from rest_framework.response import Response# 使用jwt 提供的认证类,局部使用
from rest_framework_jwt.authentication import JSONWebTokenAuthentication# 内置权限类
from rest_framework.permissions import IsAuthenticated# 但设定权限,登陆才能访问。
class OrderAPIView(APIView):authentication_classes = [JSONWebTokenAuthentication,]# 权限控制permission_classes = [IsAuthenticated,]def get(self,request):return Response('这是订单信息')class UserInfoAPIView(APIView):authentication_classes = [JSONWebTokenAuthentication,] # 可以理解成,全局设定了,游客可以访问。def get(self,request):return Response('这是UserInfoAPIView')
自定制基于jwt认证类
一、控制接口返回的数据格式
utils.py
def My_jwt_response_payload_handler(token, user=None, request=None):return {'token': token,'msg':'登录成功','status':100,'username':user.username}
settings.py
JWT_AUTH={'JWT_RESPONSE_PAYLOAD_HANDLER':'app02.utils.My_jwt_response_payload_handler'
}
二、自定义基于jwt的权限类
因为是自己定制的,所以可以返回错误信息,当没有携带token字段。这是与上面“jwt简单例子”的区别。
1.自定义验证。
utils.py
from rest_framework_jwt.authentication import BaseAuthentication
from rest_framework_jwt.authentication import BaseJSONWebTokenAuthentication
from rest_framework.exceptions import AuthenticationFailed
# from rest_framework_jwt.authentication import jwt_decode_handler
from rest_framework_jwt.utils import jwt_decode_handler # 与上面是一个
import jwt
from api import models# class MyJwtAuthentication(BaseAuthentication):
# def authenticate(self, request):
# jwt_value = request.META.get('HTTP_AUTHORIZATION')
# if jwt_value:
# try:
# # jwt 提供了通过三段token,取出payload的方法,并且有校验功能
# payload = jwt_decode_handler(jwt_value)
#
# except jwt.ExpiredSignature:
# raise AuthenticationFailed('签名过期')
# except jwt.InvalidTokenError:
# raise AuthenticationFailed('用户非法')
# except Exception as e:
# raise AuthenticationFailed(str(e))
#
# # 因为payload 就是用户信息字典
# print(payload)
# # 第一种,去数据库查
# # user=models.User.objects.get(pk=payload.get('user_id'))
# # 第二种,不查数据库
# user=models.User(id=payload.get('user_id'),username=payload.get('username'))
# return user,jwt_value
# # 没有值,直接抛异常
# raise AuthenticationFailed('没有携带认证信息')# 基于BaseJSONWebTokenAuthentication
# 可以使用内置方法获取user
class MyJwtAuthentication(BaseJSONWebTokenAuthentication):def authenticate(self, request):jwt_value = request.META.get('HTTP_AUTHORIZATION')if jwt_value:try:# jwt 提供了通过三段token,取出payload的方法,并且有校验功能payload = jwt_decode_handler(jwt_value)except jwt.ExpiredSignature:raise AuthenticationFailed('签名过期')except jwt.InvalidTokenError:raise AuthenticationFailed('用户非法')except Exception as e:raise AuthenticationFailed(str(e))# 因为payload 就是用户信息字典user=self.authenticate_credentials(payload)return user,jwt_value# 没有值,直接抛异常raise AuthenticationFailed('没有携带认证信息')
2.视图类
#
from app02.utils import MyJwtAuthentication
class GoodsInfoAPIView(APIView):authentication_classes = [MyJwtAuthentication,]def get(self,request,*args,**kwargs):print(request.user)return Response('商品信息')
3.urls.py
path('goods/', views.GoodsInfoAPIView.as_view()),