簡體   English   中英

使用 Django REST Framework 的 TokenAuthentication 查詢字符串中的令牌

[英]Token in query string with Django REST Framework's TokenAuthentication

在使用Django REST Framework構建的 API 中,可以使用 TokenAuthentication 方法完成身份驗證。 它的文檔說身份驗證令牌應該通過Authorization標頭發送。

通常可以通過查詢字符串發送 API 密鑰或令牌以進行身份​​驗證,例如https://domain.com/v1/resource?api-key=lala

有沒有辦法對 Django REST Framework 的 TokenAuthentication 做同樣的事情?

默認情況下,DRF 不支持查詢字符串進行身份驗證,但您可以輕松地在TokenAuthentication類中覆蓋其authenticate方法以支持它。

一個例子是:

class TokenAuthSupportQueryString(TokenAuthentication):
    """
    Extend the TokenAuthentication class to support querystring authentication
    in the form of "http://www.example.com/?auth_token=<token_key>"
    """
    def authenticate(self, request):
        # Check if 'token_auth' is in the request query params.
        # Give precedence to 'Authorization' header.
        if 'auth_token' in request.query_params and \
                        'HTTP_AUTHORIZATION' not in request.META:
            return self.authenticate_credentials(request.query_params.get('auth_token'))
        else:
            return super(TokenAuthSupportQueryString, self).authenticate(request)
class QueryStringBasedTokenAuthentication(TokenAuthentication):
    def authenticate(self, request):
        key = request.query_params.get('auth_token').strip()
        if key:
            return self.authenticate_credentials(key)
        return False

DRF具有TokenAuthentication ,它在header查找token 方法authenticate_credentials負責驗證令牌。

截至 2018 年,使用 Django Rest Framework,您可以創建自己的身份驗證類,請參閱http://getblimp.github.io/django-rest-framework-jwt/#extending-jsonwebtokenauthentication

class JSONWebTokenAuthenticationQS(BaseJSONWebTokenAuthentication):
    def get_jwt_value(self, request):
        return request.QUERY_PARAMS.get('jwt')

然后在 APIView 類中添加authentication_classes = (JSONWebTokenAuthenticationQS,)

或者@authentication_classes((JSONWebTokenAuthenticationQS,))

在視圖函數上。

跟進斯科特沃倫的回答。 這是朝着正確方向邁出的一步,因為 DRFJWT 文檔不包括重要的 authentication_classes 行。 但是,正如問題 441 中所述,存在一個大問題,即您不能混合使用 JWT 身份驗證方法。 我結束了:

class JSONWebTokenAuthenticationQS(JSONWebTokenAuthentication):
    def get_jwt_value(self, request):
        return request.GET.get('jwt') or JSONWebTokenAuthentication.get_jwt_value(self, request)

到目前為止似乎運作良好。 它使用 JSONWebTokenAuthentication 而不是 Base 類,因為它必須使用原始 get_jwt_value 方法。

參考OmriToptixScott Warren等網站12 的回答

現在大多數情況下使用JSONWebTokenAuthentication ,所以現在應該覆蓋它的get_jwt_value ,完整代碼是:

# from rest_framework_jwt.authentication import BaseJSONWebTokenAuthentication
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from rest_framework.authentication import get_authorization_header

class JWTAuthByQueryStringOrHeader(JSONWebTokenAuthentication):
# class JWTAuthByQueryStringOrHeader(BaseJSONWebTokenAuthentication):
    """
    Extend the TokenAuthentication class to support querystring authentication
    in the form of "http://www.example.com/?jwt_token=<token_key>"
    """

    def get_jwt_value(self, request):
        # Check if 'jwt_token' is in the request query params.
        # Give precedence to 'Authorization' header.
        queryParams = request.query_params
        reqMeta = request.META

        if ('jwt_token' in queryParams) and ('HTTP_AUTHORIZATION' not in reqMeta):
            jwt_token = queryParams.get('jwt_token')
            # got jwt token from query parameter
            return jwt_token
        else:
            # call JSONWebTokenAuthentication's get_jwt_value
            # to get jwt token from header of 'Authorization'
            return super(JWTAuthByQueryStringOrHeader, self).get_jwt_value(request)

這里將上面的代碼保存到apps/util/jwt_token.py ,然后不要忘記添加相關的Django設置:

REST_FRAMEWORK = {
    ...
    'DEFAULT_AUTHENTICATION_CLASSES': (
        # 'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
        'apps.util.jwt_token.JWTAuthByQueryStringOrHeader',
        ...
    ),
    ...
}

現在前端/網絡端可以像這樣調用api:

http://localhost:65000/api/v1/scripts/3d9e77b0-e538-49b8-8790-60301ca79e1d/script_word_export/?jwt_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiMWVkMGEwZDgtMmFiYi00MDFkLTk5NTYtMTQ5MzcxNDIwMGUzIiwidXNlcm5hbWUiOiJsc2R2aW5jZW50IiwiZXhwIjoxNTMxOTAyOTU0LCJlbWFpbCI6InZpbmNlbnQuY2hlbkBuYXR1cmxpbmcuY29tIn0.wheM7Fmv8y8ysz0pp-yUHFqfk-IQ5a8n_8OplbYkj7s

jwt_token傳遞到服務器端,獲得下載/導出文件的授權。

同時仍然支持原始方法pass jwt token inside header 'Authorization'

POST http://localhost:65000/api/v1/scripts/3d9e77b0-e538-49b8-8790-60301ca79e1d/script_word_export/
Authorization: JWT eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiMWVkMGEwZDgtMmFiYi00MDFkLTk5NTYtMTQ5MzcxNDIwMGUzIiwidXNlcm5hbWUiOiJsc2R2aW5jZW50IiwiZXhwIjoxNTMxOTAyOTU0LCJlbWFpbCI6InZpbmNlbnQuY2hlbkBuYXR1cmxpbmcuY29tIn0.wheM7Fmv8y8ysz0pp-yUHFqfk-IQ5a8n_8OplbYkj7s

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM