创建一个名为API的Django工程目录和名为Blog_RestApi的app
API----->urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('api/',include('Blog_RestApi.urls'))
]
API----->Blog_RestApi----->urls.py
from django.urls import path, include
from Blog_RestApi import views
urlpatterns=[
path('sublogin/', views.SupLoginView.as_view()),
path('suborder/', views.SubOrderView.as_view()),
]
生成jwt的token模块
Blog_RestApi---->utils---->jwt_create_token.py
import datetime
import jwt
from django.conf import settings
def create_token(payload, timeout=1):
# 盐值
salt = settings.SECRET_KEY
# 固定头部格式,也可以自己改
headers = {
'type': 'jwt',
'alg': 'HS256'
}
# 设置payload内容,目前只加一个超时时间,其他的自定义
payload['exp'] = datetime.datetime.utcnow() + datetime.timedelta(minutes=timeout)
# 生成token
token = jwt.encode(payload=payload, key=salt, headers=headers).decode("utf-8")
return token
验证token模块
Blog_RestApi---->extensions---->auth.py
import jwt
from jwt import exceptions
from rest_framework.exceptions import AuthenticationFailed
from rest_framework.authentication import BaseAuthentication
from django.conf import settings
class JWTQueryParamsAuthentication(BaseAuthentication):
def authenticate(self, request):
# 获取token并判断token的合法性
token = request.query_params.get('token')
# 盐值
salt = settings.SECRET_KEY
"""
1。切割成三部分
2。取出并解密第二部分payload:判断token是否超时
3。验证第三部分:加盐并验证token合法性
"""
try:
# 从token中获取payload并校验合法性
# jwt.decode(token,salt,True):内部集成了以上三个步骤
payload = jwt.decode(token, salt, True)
except exceptions.ExpiredSignatureError:
raise AuthenticationFailed({'code': 403, 'error': "token已经失效"})
except jwt.DecodeError:
raise AuthenticationFailed({'code': 403, 'error': "token认证失效"})
except jwt.InvalidTokenError:
raise AuthenticationFailed({'code': 403, 'error': '非法token'})
"""
def authenticate(self, request):
#验证请求并返回(用户,令牌)的二元组
#Authenticate the request and return a two-tuple of (user, token).
raise NotImplementedError(".authenticate() must be overridden.")
"""
##request.user=payload信息, request.token=token信息
return (payload, token)
数据模型
Blog_RestApi---->models.py
class User(models.Model):
username=models.CharField(max_length=32)
passwd=models.CharField(max_length=64)
##允许这个字符串为空
token=models.CharField(max_length=64,blank=True)
视图
Blog_RestApi---->views.py
from Blog_RestApi.models import User
from rest_framework.views import APIView
from rest_framework.response import Response
from Blog_RestApi.utils.jwt_create_token import create_token
##用户登陆并生成token
class SupLoginView(APIView):
#当将token验证集成到settings的时候,可通过[]避免token认证
#authentication_classes = []
def post(self, request, *args, **kwargs):
# request.data返回请求正文的解析内容
user = request.data.get('username')
pwd = request.data.get('password')
user_object = User.objects.filter(username=user, passwd=pwd).first()
##如果用户名和密码不正确
if not user_object:
return Response({'code': 403, 'error': '用户名或密码错误'})
# 生成token:
token = create_token({'id': user_object.id, 'name': user_object.username})
# 每post一次随机字符串token会变,数据库也会更新token
user_object.save()
# 返回给用户token
return Response({'code': 200, 'data': token})
from Blog_RestApi.extensions.auth import JWTQueryParamsAuthentication
##token认证
class SubOrderView(APIView):
##认证,只有通过token认证后才能执行下边试图函数
##也可以集成到settings中,让所有视图函数(除了login试图函数)都需要token认证
authentication_classes = [JWTQueryParamsAuthentication]
def get(self, request, *args, **kwargs):
#print(request.user)
return Response('验证成功')
将token验证集成到settings配置中
1.查看父类APIView中的settings
class APIView(View):
# The following policies may be set at either globally, or per-view.
renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES
parser_classes = api_settings.DEFAULT_PARSER_CLASSES
##默认的认证配置
authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES
throttle_classes = api_settings.DEFAULT_THROTTLE_CLASSES
permission_classes = api_settings.DEFAULT_PERMISSION_CLASSES
content_negotiation_class = api_settings.DEFAULT_CONTENT_NEGOTIATION_CLASS
metadata_class = api_settings.DEFAULT_METADATA_CLASS
versioning_class = api_settings.DEFAULT_VERSIONING_CLASS
# Allow dependency injection of other settings to make testing easier.
settings = api_settings
2.将token验证集成到settings配置中,
REST_FARMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': ['Blog_RestApi.extensions.auth.JWTQueryParamsAuthentication']
}
验证:
登陆生成token
正确token
token超时后
错误的token
来源:CSDN
作者:Asimov__
链接:https://blog.csdn.net/qq_41661056/article/details/103644163