【问题标题】:Django Rest Framework JWT AuthDjango Rest 框架 JWT 身份验证
【发布时间】:2019-03-01 22:34:48
【问题描述】:

我在登录 JWT 后发布/获取任何请求时遇到问题。 (我正在使用djangorestframework-jwt 库)用户成功登录,应用程序返回 json 令牌,但是当我将此令牌用于下一个请求时,我得到了

{
    "detail": "Authentication credentials were not provided."
}

settings.py

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.BasicAuthentication',
    ),
}

JWT_AUTH = {
    'JWT_ALLOW_REFRESH': True,
    'JWT_EXPIRATION_DELTA': datetime.timedelta(hours=1),
    'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(days=7),
}

登录查看

def post(self, request, format=None):

    if not request.data:
        return Response({'Error': "Please provide username/password"},  status=status.HTTP_400_BAD_REQUEST)

    username = request.data['username']
    password = request.data['password']

    try:
        user = User.objects.get(email=username, password=password)
    except User.DoesNotExist:
        return Response({'Error': "Invalid username/password"}, status=status.HTTP_400_BAD_REQUEST)

    if user:
        payload = {
            'id': user.id,
            'email': user.email,
            'first_name': user.first_name
        }

        jwt_token = jwt.encode(payload, "SECRET_KEY")  # to be changed

        return Response({'token': jwt_token}, status=status.HTTP_200_OK)

然后每个其他视图都包含

 authentication_class = (JSONWebTokenAuthentication,)
 permission_classes = (IsAuthenticated,)

我已经使用 postman 和 curl 进行了测试,但我得到了同样的错误。不确定标题格式是否有错误,或者是否还有其他我遗漏的东西。任何帮助将不胜感激!

编辑: 我已将设置更改为

'DEFAULT_AUTHENTICATION_CLASSES': (
    'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
    'rest_framework.authentication.SessionAuthentication',
    'rest_framework.authentication.BasicAuthentication',
),

但现在我明白了

{
    "detail": "Error decoding signature."
}

编辑:我认为问题在于jwt_token = jwt.encode(payload, 'SECRET_KEY') 可能会返回一个无法识别的令牌...如果我使用obtain_jwt_token 生成的令牌,那么我可以查询任何端点。谁能解释一下?

编辑:所以我更改为jwt_token = jwt_encode_handler(payload),设置文件包含JWT_SECRET_KEY(当我验证登录jwt后收到的令牌时,它确实是具有正确有效负载和秘密的正确令牌)但它仍然是无法识别"detail": "Invalid signature."

【问题讨论】:

  • @JPG 就是这样,当我尝试验证时遇到同样的错误
  • jwt 令牌使用密钥进行加密和签名。当您使用 jwt.encode 创建自定义令牌并将机密用作“SECRET_KEY”时,需要使用相同的密钥进行解码。小鬼。 'SECRET_KEY' 是一个字符串。请参阅我在下面发布的答案,并在您的设置文件中添加一个密钥变量。

标签: django-rest-framework jwt


【解决方案1】:

我设法解决了我的问题。在对用户进行身份验证时,我正在检查我之前创建的自定义 user 表,这与 django 的 auth_user 表不同。我更改了 django 的设置以使用我的自定义用户表,然后使用来自身份验证的令牌也适用于其他请求。

AUTH_USER_MODEL = 'main.User'

【讨论】:

    【解决方案2】:

    问题是您使用“SECRET KEY”对 JWT 进行编码并使用另一个密钥进行解码。 jwt 使用的默认密钥是 settings.SECRET_KEY。但是,当您创建自定义 jwt 令牌时,您使用字符串作为秘密“SECRET_KEY”。但是您使用默认的 jwt 验证,它会自动使用 settings.SECRET_KEY。 因此,将'JWT_SECRET_KEY': settings.SECRET_KEY, 添加到您的 JWT 设置中,并使用此密钥进行编码和解码。 例如:

    jwt_token = jwt.encode(payload, settings.SECRET_KEY)
    

    或者您可以覆盖 jwt 验证并创建自己的验证。

    【讨论】:

      猜你喜欢
      • 2021-12-21
      • 2019-07-11
      • 2018-10-17
      • 2019-05-02
      • 2013-06-29
      • 2017-09-26
      • 2017-11-02
      • 1970-01-01
      • 2019-01-01
      相关资源
      最近更新 更多