简体   繁体   English

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

[英]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参考OmriToptixScott Warren等网站12 的回答

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.

相关问题 Django Rest框架TokenAuthentication不起作用 - django rest framework TokenAuthentication not working Django REST Framework TokenAuthentication 一般在 Django 中进行身份验证 - Django REST Framework TokenAuthentication to authenticate in Django generally Django REST框架TokenAuthentication返回匿名用户 - Django REST framework TokenAuthentication returns anonymous user 在 django rest 框架(使用 TokenAuthentication)公共 APIView 上获取 CSRF 令牌丢失错误 - Getting CSRF token missing error on a django rest framework (with TokenAuthentication) public APIView &quot;detail&quot;: &quot;方法 \\&quot;GET\\&quot; 不允许。&quot; 在 TokenAuthentication Django 休息框架中 - "detail": "Method \"GET\" not allowed." in TokenAuthentication Django rest framework 如何在django-rest-framework中使用TokenAuthentication for API - How to use TokenAuthentication for API in django-rest-framework 根据请求的类型,在API视图的一部分上应用tokenauthentication Django rest框架 - Apply tokenauthentication Django rest framework on part of the API view based on the type of the request 在 Django Rest 框架中使用 Tokenauthentication 进行身份验证时,last_login 字段未更新 - last_login field is not updated when authenticating using Tokenauthentication in Django Rest Framework 在模板中显示用户的 Django Rest Framework Auth 令牌 - Display User's Django Rest Framework Auth token in templates Django REST框架验证令牌 - Django REST Framework Auth Token
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM