使用Django REST Framework的TokenAuthentication在查询字符串中进行标记

时间:2015-04-03 13:46:23

标签: python django authentication django-rest-framework

在使用Django REST Framework身份验证构建的API中,可以使用TokenAuthentication方法完成。其documentation表示身份验证令牌应通过Authorization标头发送。

通常可以通过查询字符串发送API密钥或令牌以进行身份​​验证,例如https://domain.com/v1/resource?api-key=lala

有没有办法对Django REST Framework的TokenAuthentication做同样的事情?

5 个答案:

答案 0 :(得分:10)

默认情况下,DRF不支持要进行身份验证的查询字符串,但您可以轻松覆盖authenticate类中的TokenAuthentication方法以支持它。

一个例子是:

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)

答案 1 :(得分:6)

class QueryStringBasedTokenAuthentication(TokenAuthentication):
    def authenticate(self, request):
        key = request.query_params.get('auth_token').strip()
        if key:
            return self.authenticate_credentials(key)
        return False

DRFTokenAuthentication,在token中查找header。方法authenticate_credentials负责验证令牌。

答案 2 :(得分:2)

从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,))

在视图功能上。

答案 3 :(得分:1)

关注Scott Warren的回答。这是朝正确方向迈出的一步,因为DRFJWT文档未包含重要的authentication_classes行。但是,正如Issue 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方法。

答案 4 :(得分:-1)

请参考TerminatedOmriToptix以及其他网站12的答案

在大多数情况下,请使用Scott Warren,因此现在应覆盖其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

现在前端/网络端可以像这样调用api:

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

要将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'