首先创建一个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 = {'typ': 'jwp', 'alg': 'default'}
key = settings.secret_key
salt = "ess"
def encrypt(obj):
"""加密: signing 加密 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(payload)
# 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_whitelist)
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 - 设置了路由白名单
发表评论