[英]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 方法。
參考OmriToptix
和Scott Warren
等網站1和2 的回答
現在大多數情況下使用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.