Django token 生成与验证

首先创建一个Django 项目,我这里以 demo为例,作为示例先不创建app了

然后再 demo 目录下创建 views.py 和 utils 目录,在目录下分别创建 token.pymiddleware.pyinit.py,然后目录格式如下图

接下来完成views.pytoken.pymiddleware.py 中的内容了,首先是 token.py

python 复制代码
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 的路由

python 复制代码
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

python 复制代码
from django.http import JsonResponse
from demo.utils.token import create_token

def index(request):
    return JsonResponse({'code': 0, 'message': 'Hello, world!'})

接着是 url.py,需要设置一下请求路径

python 复制代码
from django.urls import path
from demo import views

urlpatterns = [
    path('index/', views.index),
]

接着再 settings.py 文件中 设置我们的中间件,这样每次请求都会先校验 token 了

python 复制代码
MIDDLEWARE = [
    'demo.utils.middleware.AuthorizeMiddleware', # 一定要放在最上面,有cors的话放cors下面
    '···',
]

到这为止 就已经完成了所有的配置,下面图1 和图2分别是 设置和没设置请求路径白名单的效果
图1 - 没有设置路由白名单

图2 - 设置了路由白名单

相关推荐
Dxy12393102167 分钟前
Python如何使用DrissionPage做自动化:简单入门指南
开发语言·python·自动化
石去皿9 分钟前
从本地知识库到“活”知识——RAG 落地全景指南
c++·python·大模型·rag
hui函数13 分钟前
Python系列Bug修复PyCharm控制台pip install报错:如何解决 pip install 网络报错 企业网关拦截 User-Agent 问题
python·pycharm·bug
a努力。15 分钟前
虾皮Java面试被问:JVM Native Memory Tracking追踪堆外内存泄漏
java·开发语言·jvm·后端·python·面试
Kratzdisteln16 分钟前
【Python】Flask
开发语言·python·flask
sa1002733 分钟前
基于Python的京东评论爬虫
开发语言·爬虫·python
Cigaretter71 小时前
Day 38 早停策略和模型权重的保存
python·深度学习·机器学习
DXDZ20221 小时前
12V大功率ESD产品TVS20H12T5G 5000W 200A VC24V助力快充接口浪涌防护
5g·django·symfony
sunywz1 小时前
【JVM】(2)java类加载机制
java·jvm·python
Silence_Jy1 小时前
GPU架构
python