Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django REST框架-为自定义JWT身份验证重写JSONWebTokenAuthentication_Django_Authentication_Jwt - Fatal编程技术网

Django REST框架-为自定义JWT身份验证重写JSONWebTokenAuthentication

Django REST框架-为自定义JWT身份验证重写JSONWebTokenAuthentication,django,authentication,jwt,Django,Authentication,Jwt,我有一个带有外部数据库的Django应用程序,这意味着对于每个用户请求,我都向外部DB服务器发送SQL查询。不存在本地数据库(如sqllite等)。此外,JWT还应用于对用户进行身份验证。 为此,我已覆盖了获取JSONWebToken视图: class ObtainJWT(ObtainJSONWebToken): def post(self, request, *args, **kwargs): username = request.data.get('username'

我有一个带有外部数据库的Django应用程序,这意味着对于每个用户请求,我都向外部DB服务器发送SQL查询。不存在本地数据库(如sqllite等)。此外,JWT还应用于对用户进行身份验证。 为此,我已覆盖了
获取JSONWebToken
视图:

class ObtainJWT(ObtainJSONWebToken):
    def post(self, request, *args, **kwargs):
        username = request.data.get('username')
        password = request.data.get('password')

        # verify that user with given credentials exist in db
        resp = requests.post(settings.SERVER_HOST+"/auth/",
                             json={"username":username, "password":password})
        if resp.status_code == status.HTTP_401_UNAUTHORIZED:
            return Response({'error':'Invalid credentials'},
                            status=status.HTTP_401_UNAUTHORIZED)

        # create token
        payload = jwtutils.jwt_payload_handler(username, password, api_settings.JWT_EXPIRATION_DELTA)
        token = jwt_encode_handler(payload)
        return Response({'token': token},
                        status=status.HTTP_200_OK)
jwtutils
中的
jwt\u有效载荷处理程序

def jwt_payload_handler(username, password, delta):
    # custom payload handler
    payload = {
        'username': username,
        'password': password,
        'exp': datetime.utcnow() + delta
    }

    return payload
现在我可以不使用任何
用户
对象成功获取令牌。但是当使用获得的令牌时(用户尝试使用令牌访问受保护的路由),
{“detail”:“Invalid signature.”}
返回。我认为这是因为我使用的DRF的
JSONWebTokenAuthentication
类有
authenticate\u credentials
方法来检查本地数据库()中是否存在具有给定凭据的用户,因此出现了错误。所以我决定创建自定义身份验证类。 下面是我写的:

class JSONWebTokenAuthentication(BaseAuthentication):
"""
Token based authentication using the JSON Web Token standard.
"""
def get_jwt_value(self, request):
    auth = get_authorization_header(request).split()
    auth_header_prefix = api_settings.JWT_AUTH_HEADER_PREFIX.lower()

    if not auth:
        if api_settings.JWT_AUTH_COOKIE:
            return request.COOKIES.get(api_settings.JWT_AUTH_COOKIE)
        return None

    if smart_text(auth[0].lower()) != auth_header_prefix:
        return None

    if len(auth) == 1:
        msg = _('Invalid Authorization header. No credentials provided.')
        raise exceptions.AuthenticationFailed(msg)
    elif len(auth) > 2:
        msg = _('Invalid Authorization header. Credentials string '
                'should not contain spaces.')
        raise exceptions.AuthenticationFailed(msg)

    return auth[1]

def authenticate(self, request):
    """
    Returns a two-tuple of `User` and token if a valid signature has been
    supplied using JWT-based authentication.  Otherwise returns `None`.
    """
    jwt_value = self.get_jwt_value(request)
    if jwt_value is None:
        return None

    try:
        payload = jwt_decode_handler(jwt_value)
    except jwt.ExpiredSignature:
        msg = ('Signature has expired.')
        raise exceptions.AuthenticationFailed(msg)
    except jwt.DecodeError:
        msg = _('Error decoding signature.')
        raise exceptions.AuthenticationFailed(msg)
    except jwt.InvalidTokenError:
        raise exceptions.AuthenticationFailed()

    return (None, payload)
然而,这是行不通的。我返回的是
None
而不是有效的
User
对象。在Django的身份验证过程的稍后某个地方,如果值
已通过身份验证()
返回
True
,则读取并测试该值。返回
None
显然会导致
{“详细信息”:“您没有执行此操作的权限”。}


我对Django和JWT比较陌生,重写身份验证类的最佳方法是什么,这样我就不会在本地保存任何Django
User
s,也不会破坏Django身份验证过程中的任何内容?或者我需要重写一些权限类?提前感谢。

不确定您是否解决了此问题,但您是否在rest框架设置中添加了自定义身份验证类?大概是这样的:

  REST_FRAMEWORK = {
        'DEFAULT_AUTHENTICATION_CLASSES': (
            'myapp.location.JSONWebTokenAuthentication' #location of your custom authentication class.
        ),
    }