流程:
登录后生成token返回给用户。
用户拿token可以访问其它视图。,token错误或过期则无法正常访问。
生成token
创建一个py文件
import jwt
import datetime
from django.conf import settings
from jwt import exceptions
salt = settings.SECRET_KEY
def create_token(payload, timeout=1):
headers = {
'trp': 'jwt',
'alg': 'HS256'
}
payload['exp'] = datetime.datetime.utcnow(
) + datetime.timedelta(minutes=timeout)
token = jwt.encode(payload=payload, key=salt, algorithm='HS256', headers=headers).decode('utf-8')
return token
检验token
创建一个py文件
from django.conf import settings
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed=
import jwt
from jwt import exceptions
from django.conf import settings
salt = settings.SECRET_KEY
def parse_payload(token):
"""
对token进行和发行校验并获取payload
:param token:
:return:
"""
result = {'status': False, 'data': None, 'error': None}
try:
verified_payload = jwt.decode(token, salt, True)
result['status'] = True
result['data'] = verified_payload
except exceptions.ExpiredSignatureError:
result['error'] = 'token已失效'
except jwt.DecodeError:
result['error'] = 'token认证失败'
except jwt.InvalidTokenError:
result['error'] = '非法的token'
return result
class JwtQueryParamsAuthentication(BaseAuthentication):
def authenticate(self, request):
# 非登录页面需要校验token
authorization = request.META.get('HTTP_AUTHORIZATION', '')
auth = authorization.split()
if not auth:
raise AuthenticationFailed({'error': '未获取到Authorization请求头', 'status': False})
if auth[0].lower() != 'bearer':
raise AuthenticationFailed(
{'error': 'Authorization请求头中认证方式错误', 'status': False})
if len(auth) == 1:
raise AuthenticationFailed({'error': "非法Authorization请求头", 'status': False})
elif len(auth) > 2:
raise AuthenticationFailed({'error': "非法Authorization请求头", 'status': False})
token = auth[1]
result = parse_payload(token)
if not result['status']:
raise AuthenticationFailed(result)
# 如果想要request.user等于用户对象,此处可以根据payload去数据库中获取用户对象。
return (result, token)
settings配置
REST_FRAMEWORK = {
# 认证
'DEFAULT_AUTHENTICATION_CLASSES': [
'utils.auth.JwtQueryParamsAuthentication', # 同名文件自己的路径
],
}
视图文件示例
登录后生成token
import jwt
from jwt import exceptions
class LoginView(APIView):
authentication_classes = []
def post(self, request, *args, **kwargs):
user = request.data.get('username')
pwd = request.data.get('password')
user_object = User.objects.filter(username=user).first()
if not user_object.check_password(pwd):
return Response({'msg': '用户名或密码错误'})
token = create_token({'id': user_object.id, 'username': user_object.username})
return Response({'code':'1001', 'data': token})
用拿到的token访问其它视图
class ProOrderView(APIView):
def get(self, request, *args, **kwargs):
return Response('成功')