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