jwt,token白名单过滤。从写中间件。生成token

目录

生成touken

解析token

中间件

封装

调用


生成touken

        里面的SECRET_KEY需要从配置文件中settings中导过来。

class UserS(APIView):
    def post(self, request):
        uname = request.data.get("uname")
        upwd = request.data.get("upwd")

        data = User.objects.filter(uname=uname, upwd=upwd).first()
        # 添加一个过期时间2分钟
        current_time = datetime.datetime.now()
        future_time = current_time + datetime.timedelta(seconds=120)

        if data is None:
            return Response({
                "code": 400,
                "msg": "登录失败"
            })
        token = jwt.encode({
            "uname": data.uname,
            "user_id": data.id,
            "time": future_time.strftime("%Y-%m-%d %H:%M:%S")
        }, SECRET_KEY)
        return Response({
            "code": 200,
            "msg": "登录成功",
            "data": token
        })

解析token

中间件

        从写中间件,在settings文件里面的加上“MIDDLEWARE”中加上封装的

MIDDLEWARE = [
    "corsheaders.middleware.CorsMiddleware",
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    # 'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    "从封装中一级一级导过来",
]
封装

        封装一个token进行解析判断,校验。

import jwt                                  # 导入 jwt 模块用于解析和生成 JSON Web Token
import time                                 # 导入 time 模块用于获取当前时间
import datetime                             # 导入 datetime 模块用于处理日期和时间

from django.utils.deprecation import MiddlewareMixin      # 导入 MiddlewareMixin 类,用于创建中间件类
from django.http import JsonResponse                     # 导入 JsonResponse 类用于返回 JSON 格式的响应
from Smart_Farm.settings import SECRET_KEY               # 导入 SECRET_KEY 变量,用于解析 JSON Web Token

class PomitionWare(MiddlewareMixin):
    def process_request(self, request):
        whitelist = ["/user/"]                            # 定义白名单,路径在白名单中的请求将不会受到中间件的影响,不需要登录就能查看的功能路径写在这里面,登录的路径也要写在这里面

        if request.path_info not in whitelist:            # 检查请求路径是否在白名单中
            try:
                # 获取token
                token = request.META.get('HTTP_AUTHORIZATION', '')  # 从请求头中获取 Authorization 字段的值作为 token
                print(token)
                if not token:                                   # 如果 token 为空,则说明未提供身份验证信息
                    return JsonResponse({                       # 返回身份验证失败的响应
                        "code": 401,
                        "msg": "没有权限"
                    })

                # 解析token
                try:
                    payload = jwt.decode(token, SECRET_KEY, algorithms=['HS256'])       # 使用 SECRET_KEY 解析 token
                    shi = payload["time"]                                             # 从解析后的 token 中获取时间字段
                    id = payload["user_id"]                                          # 从解析后的 token 中获取用户ID字段
                    request.userid = id                       # 将用户ID存储在请求对象中,以便后续视图函数使用
                    datetime_obj = datetime.datetime.strptime(shi, '%Y-%m-%d %H:%M:%S')  # 将字符串格式的时间转换为 datetime 对象
                    timestamp = datetime_obj.timestamp()                               # 将 datetime 对象转换为时间戳

                    now = int(time.time())                                               # 获取当前时间的时间戳

                    print(now,timestamp)

                    if timestamp < now:                                                  # 检查 token 中的时间是否早于当前时间
                        return JsonResponse({"code": 403, "msg": "token已过期"})         # 返回 token 已过期的响应
                except jwt.ExpiredSignatureError:
                    return JsonResponse({"code": 403, "msg": "token已过期"})             # 返回 token 已过期的响应
                except jwt.InvalidTokenError:
                    return JsonResponse({"code": 401, "msg": "无效的token"})             # 返回无效 token 的响应

            except Exception as e:
                return JsonResponse({"code": 402, "msg": "解析token出错"})                 # 返回解析 token 出错的响应
调用

        如果需要用户的id可以调用request.id。上面把用户id存到request里面了。

class Yan(APIView):
    def get(self, request):
        # 从request中拿到用户的id
        id = request.userid
        print(id)

        return Response({
            "code": 200,
            "msg": "成功"
        })