jwt简单例子
一、登陆设置
1.不需要写login的视图类,使用jwt内置的。
2.需要前置条件,已有继承AbstractUser models,并且有数据,用于校验,返回token。
urls.py
from rest_framework_jwt.views import obtain_jwt_token
urlpatterns = [
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()),