Django token 生成与验证的实现
首先创建一个Django 项目,我这里以 demo为例,作为示例先不创建app了
然后再 demo 目录下创建 views.py 和 utils 目录,在目录下分别创建 token.py ,middleware.py ,__init__.py,然后目录格式如下图
接下来完成views.py 和 token.py 和 middleware.py 中的内容了,首先是 token.py
import time import hashlib from demo import settings from django.core import signing from datetime import datetime, timedelta HEADER =http://www.devze.com {'typ': 'Jwp', 'alg': 'default'} KEY = settings.SECRET_KEY SALT = "ESS" def encrypt(obj): """加密: signing 加密android and Base64 编码""" value = signing.dumps(obj, key=KEY, salt=SALT) value = signing.b64_encode(value.encode()).decode() return value def decrypt(src): """解密: Base64 解码 and signing 解密""" src = signing.b64_decode(src.encode()).decode() raw = signing.loads(src, key=KEY, salt=SALT) return raw def create_token(username): """生成token信息""" # 1. 加密头信息 header = encrypt(HEADER) # 2. 构造Payload(有效期31天) payload = { "username": username, "iat": time.time(), "exp": (datetime.utcnow() + timedelta(hours=8,days=31)).strftime("%Y-%m-%d") } payload = encrypt(paylo编程ad) # 3. MD5 生成签名 md5 = hashlib.md5() md5.update(("%s.%s" % (header, payload)).encode()) signature = md5.hexdigest() token = "%s.%s.%s" % (header, payload, signature) return token def get_payload(token): """解析 token 获取 payload 数据""" payload = str(token).split('.')[1] payload = decrypt(payload) return payload def get_username(token): """解析 token 获取 username""" payload = get_payload(token) return payload['username'] def get_exp_time(token): """解析 token 获取过期时间""" payload = get_payload(token) return payload['exp'] def check_token(username, token): """验证 token: 检查 username 和 token 是否一致且未过期""" return get_username(token) == username and get_exp_time(token) > (datetime.utcnow() + timedelta(hours=8)).strftime('%Y-%m-%d')
接着是 middleware.py 文件,记得配置 路由白名单,即不需要验证 token 的路由
from .token import check_token from django.http import jsonResponse try: from django.utils.deprecation import MiddlewareMixin # Django 1.10.x except ImportError: MiddlewareMixin = object # 白名单,表示请求里面编程的路由时不验证登录信息 API_WHITELIST = ['/index/', '/index', 'index/'] class AuthorizeMiddleware(MiddlewareMixin): def process_request(self, request): print(request.path) print(request.path not in API_WHITELIphpST) if request.path not in API_WHITELIST: if "sites" in request.path: pass else: # 从请求头中获取 username 和 token username = request.META.get("HTTP_USERNAME") token = request.META.get("HTTP_AUTHORIZATION") if username is None or token is None: return JsonResponse({"code": -2, "msg": "未查询到登录信息"}) else: # 调用 check_token 函数验证 if check_token(username, token): pass else: return JsonResponse({"code": -2, "msg": "登录信息错误或已过期"})
接着是 views.py
from django.http import JsonResponse from demo.utils.token import create_token def index(request): return JsonResponse({'code': 0, 'message': 'Hello, world!'})
接着是 url.py,需要设置一下请求路径
from django.urls import path from demo import views urlpatterns = [ path('index/', views.index), ]
接着再 settings.py 文件中 设置我们的中间件,这样每次请求都会先校验 token 了
MIDDLEWARE = [ 'demo.utils.middleware.AuthorizeMiddleware', # 一定要放在最上面,有cors的话放cors下面 '', ]
到这为止 就已经完成了所有的配置,下面图1 和图2分别是 设置和没设置请求路径白名单的效果
图1 - 没有设置路由白名单
图2 - 设置了路由白名单
精彩评论