[英]Token in query string with Django REST Framework's TokenAuthentication
In an API built with Django REST Framework authentication can be done using the TokenAuthentication method.在使用Django REST Framework构建的 API 中,可以使用 TokenAuthentication 方法完成身份验证。 Its documentation says the authentication token should be sent via an
Authorization
header.它的文档说身份验证令牌应该通过
Authorization
标头发送。
Often one can send API-keys or tokens via a query string in order to authenticate, like https://domain.com/v1/resource?api-key=lala
.通常可以通过查询字符串发送 API 密钥或令牌以进行身份验证,例如
https://domain.com/v1/resource?api-key=lala
。
Is there a way to do the same with Django REST Framework's TokenAuthentication?有没有办法对 Django REST Framework 的 TokenAuthentication 做同样的事情?
By default DRF doesn't support query string to authenticate, but you can easily override their authenticate
method in TokenAuthentication
class to support it.默认情况下,DRF 不支持查询字符串进行身份验证,但您可以轻松地在
TokenAuthentication
类中覆盖其authenticate
方法以支持它。
An example would be:一个例子是:
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
has TokenAuthentication
which looks for token
in header
. DRF
具有TokenAuthentication
,它在header
查找token
。 The method authenticate_credentials
takes care verifying the token.方法
authenticate_credentials
负责验证令牌。
As of 2018 using Django Rest Framework you can create your own Authentication class see http://getblimp.github.io/django-rest-framework-jwt/#extending-jsonwebtokenauthentication截至 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')
Then in the APIView class add authentication_classes = (JSONWebTokenAuthenticationQS,)
然后在 APIView 类中添加
authentication_classes = (JSONWebTokenAuthenticationQS,)
Or @authentication_classes((JSONWebTokenAuthenticationQS,))
或者
@authentication_classes((JSONWebTokenAuthenticationQS,))
On the view function.在视图函数上。
Following up on Scott Warren's answer.跟进斯科特沃伦的回答。 That was a step in the right direction, because the DRFJWT docs don't include the important authentication_classes line.
这是朝着正确方向迈出的一步,因为 DRFJWT 文档不包括重要的 authentication_classes 行。 But with that, as noted in Issue 441 there is a big problem that you can't mix the JWT authentication methods.
但是,正如问题 441 中所述,存在一个大问题,即您不能混合使用 JWT 身份验证方法。 I ended up with:
我结束了:
class JSONWebTokenAuthenticationQS(JSONWebTokenAuthentication):
def get_jwt_value(self, request):
return request.GET.get('jwt') or JSONWebTokenAuthentication.get_jwt_value(self, request)
which so far seems to work well.到目前为止似乎运作良好。 It uses JSONWebTokenAuthentication instead of the Base class, because it has to in order to use the original get_jwt_value method.
它使用 JSONWebTokenAuthentication 而不是 Base 类,因为它必须使用原始 get_jwt_value 方法。
refer answer of OmriToptix
and Scott Warren
and others website 1 and 2参考
OmriToptix
和Scott Warren
等网站1和2 的回答
for now most case use JSONWebTokenAuthentication
, so now should override its get_jwt_value
, full code is:现在大多数情况下使用
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)
here save above code to apps/util/jwt_token.py
, then NOT FORGET add related Django
settings:这里将上面的代码保存到
apps/util/jwt_token.py
,然后不要忘记添加相关的Django
设置:
REST_FRAMEWORK = {
...
'DEFAULT_AUTHENTICATION_CLASSES': (
# 'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
'apps.util.jwt_token.JWTAuthByQueryStringOrHeader',
...
),
...
}
now frontend/web side can call api like this:现在前端/网络端可以像这样调用api:
http://localhost:65000/api/v1/scripts/3d9e77b0-e538-49b8-8790-60301ca79e1d/script_word_export/?jwt_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiMWVkMGEwZDgtMmFiYi00MDFkLTk5NTYtMTQ5MzcxNDIwMGUzIiwidXNlcm5hbWUiOiJsc2R2aW5jZW50IiwiZXhwIjoxNTMxOTAyOTU0LCJlbWFpbCI6InZpbmNlbnQuY2hlbkBuYXR1cmxpbmcuY29tIn0.wheM7Fmv8y8ysz0pp-yUHFqfk-IQ5a8n_8OplbYkj7s
to pass jwt_token
into server side, get authorized to download/export the file.将
jwt_token
传递到服务器端,获得下载/导出文件的授权。
while still support original method pass jwt token inside header 'Authorization'
:同时仍然支持原始方法
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.