如何在 DRF 中使用身份服务器 4 验证 JWT 令牌?

Posted

技术标签:

【中文标题】如何在 DRF 中使用身份服务器 4 验证 JWT 令牌?【英文标题】:How to validate JWT token using identity server 4 in DRF? 【发布时间】:2021-04-10 05:42:42 【问题描述】:

我有一个 identityserver4、一个前端 Angular 应用程序和一个 Django REST 框架资源 API。如果未登录,Angular 应用程序将无法访问,并重定向到 identityserver4。用户必须在那里登录并被重定向到前端。到目前为止一切顺利,提供者为前端提供了一个 JWT 访问令牌。

然后前端应用程序向提供 JWT 的 DRF API 请求资源。这就是我卡住的地方,我在谷歌上找到的所有教程都解释了如何创建自己的提供者。但我只想获取令牌,与身份服务器 4 确认它是否有效,验证用户,提供资源

任何代码 sn-p 或库都会非常有用。

谢谢。

【问题讨论】:

使用 JWT,首先需要获取访问令牌,比如说 /get-token/,它将用户名和密码作为 POST 表单数据,如果凭据有效,则生成令牌,如果凭据有效,响应将包含访问和刷新令牌。您现在可以在所有后续 API 调用中使用收到的访问令牌。希望它能回答你的问题 @danish_wani 我已经拥有身份服务器生成的访问令牌。 Angular 应用程序在授权标头中传递该访问令牌以调用 Django rest api。我的要求是验证来自外部提供商的令牌,然后在 DRF 中继续请求 IdentityServer4 是用于 ASP.NET Core 2 的 OpenID Connect 和 OAuth 2.0 框架 [来源:docs.identityserver.io/en/release/index.html]。我不确定您是否可以将 django 框架与 IdentityServer4 一起使用。 @danish_wani 是的,Identityserver4 建立在 .net 核心之上。但是在 Django rest 框架中,我需要一个接口,可以通过与颁发者握手来验证提供的令牌是否有效,而在我的情况下,颁发者是 identityserver4,我需要这样的库 抱歉,我帮不了你。等待合适的人来帮助你 【参考方案1】:

我有一个类似的问题,我还没有完全解决,但也许这可以帮助你。

它是一个权限类,仅检查给定 jwt 是否使用authlib 正确编码和签名,从那里您可以访问令牌内部信息以进行进一步验证。

permissions.py:

from authlib.jose import jwt
from rest_framework import permissions
from rest_framework.exceptions import APIException

class TokenNotValid(APIException):
    status_code = 403
    default_detail = "Invalid or absent JWT token field."

class NoAuthHeader(APIException):
    status_code = 403
    default_detail = "Absent 'Authorization' header."


class ValidJWTPermission(permissions.BasePermission):
    """
    Global permission check for JWT token.
    """

    def _get_pubkey(self):
        # You will probably need to change this to get the
        # public key from your identity server and not from a file.
        with open("../public.pem", "rb") as key_file:
            pubk = key_file.read()
        return pubk

    def has_permission(self, request, view):

        auth_header = request.META.get('HTTP_AUTHORIZATION')
        # print("Received header:")
        # print(auth_header)
        if auth_header is None:
            raise NoAuthHeader

        try:
            token = auth_header.split()[1]
            # print("Encoded Token:")
            # print(token)
            dec_token = jwt.decode(token,self._get_pubkey())
        except Exception:
            # Probably should add proper exception handling.
            raise TokenNotValid

        # print("Decoded token:")
        # print(dec_token)

        return True

views.py:

from .permissions import ValidJWTPermission

class HelloView(APIView):
    permission_classes = [ValidJWTPermission]

    def get(self, request):
        return HttpResponse("Hello, world. You're at the gerenciador index.")

【讨论】:

以上是关于如何在 DRF 中使用身份服务器 4 验证 JWT 令牌?的主要内容,如果未能解决你的问题,请参考以下文章

Django Rest Framework(DRF) Json Web Token(JWT) 身份验证和登录过程

DRF JWT 身份验证对象没有属性“id”

如何在 DRF 测试中使用 JWT 令牌?

DRF 简单 jwt 从用户实例获取身份验证令牌或更改用户名和密码组合

DRF:如何将 django-rest-framework-jwt 集成到 Djoser

DRF JWT使用