Django 的登录验证装饰器

# 装饰器
def auth(view):
    def wrapper(request: HttpRequest, *args, **kwargs):
        # 自定义header jwt
        payload = request.META.get('HTTP_AUTH', None)  # 会被加前缀HTTP_且全大写, header 写 auth 就行, 跨域时头部也需要加 auth
        # print(request.META)
        if not payload:  # None没有拿到,认证失败
            return JsonResponse({'status_code': 1003, 'msg': 'token 缺失'})

        verify_status, payload_data = JwtToken.parse_token(payload)
        if verify_status:
            user_id = payload_data.get('user_id', -1)
            user = User.objects.filter(pk=user_id).get()
            request.user = user  # 如果正确,则注入user
        else:
            return JsonResponse(payload_data)

        ret = view(request, *args, **kwargs)  # 调用视图函数
        # 特别注意view调用的时候,里面也有返回异常
        return ret

    return wrapper


# tools.py
class JwtToken(object):
    _salt = SECRET_KEY

    _expire_message = dict(status_code=1004, msg="token 已经失效")

    _unknown_error_message = dict(status_code=1005, msg="token 解析失败")

    @classmethod
    def generate_token(cls, payload: dict) -> str:
        headers = dict(typ="jwt", alg="HS256")
        result = jwt.encode(payload=payload, key=cls._salt, algorithm="HS256", headers=headers)
        return result

    @classmethod
    def parse_token(cls, token: str) -> tuple:
        verify_status = False
        try:
            payload_data = jwt.decode(token, cls._salt, algorithms=['HS256'])
            verify_status = True
        except jwt.ExpiredSignatureError:
            payload_data = cls._expire_message
        except Exception as _err:
            payload_data = cls._unknown_error_message
        return verify_status, payload_data

# urls.py
path(r'xxxx/<int:year>/', views.test),
re_path(r'xxxx/(\d+)/', views.test),


# views.py
@auth
def test(request: HttpRequest, *args, **kwargs):
    print(args)
    print(kwargs)

ps:
装饰器内参数一定加上 *args, **kwargs。
url 为 <int: year> 时,year 存在 kwargs 里
url 为 re_path(r'xxxx/(\d+)/',正则匹配的数字在 args 里
view 函数需要就添加对应的 args kwargs

posted @ 2022-05-18 18:06  且听风吟也  阅读(150)  评论(0编辑  收藏  举报