1. 程式人生 > 其它 >Django 的登入驗證裝飾器

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