标签: django-rest-framework-simplejwt

使用 JWT 令牌对 Django Rest Framework 中的 POST 请求进行未经授权的响应

我正在使用 Django Rest Framework 构建 REST API。我目前有一个问题,我的一些端点返回 HTTP 401 Unauthorized,而我的绝大多数端点返回正确的响应。对于身份验证,我将 JWT 令牌与 djangorestframework-simplejwt 一起使用。

我已将 Django 配置为将令牌身份验证与 djangorestframework-simplejwt 结合使用。

# rest framework config settings
REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated',
        # 'rest_framework.permissions.AllowAny',
    ],
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.TokenAuthentication',
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    ],
Run Code Online (Sandbox Code Playgroud)

当我在请求中传递有效的访问令牌时,我的绝大多数端点都会返回有效数据。如果我没有发送有效的令牌,我会收到 HTTP 403。

另一方面,我有一些自定义 API 视图,无论我是否传递有效令牌,它们都会返回 HTTP 401。

我已将代码包含在下面的一个有问题的视图中。

class CheckDifferentialView(generics.GenericAPIView):
    permission_classes = [IsAuthenticated]
    authentication_classes = [TokenAuthentication]
    serializer_class = QuizDifferentialSerializer

    def post(self, request, *args, **kwargs):
        """
            A function to check a quiz question and to update a user's record of questions …
Run Code Online (Sandbox Code Playgroud)

python django django-rest-framework django-rest-framework-jwt django-rest-framework-simplejwt

6
推荐指数
1
解决办法
6188
查看次数

使用 Django Rest Framework Simple JWT TokenRefresh 返回用户名和 ID

我使用 Django Rest Framework 和 django-rest-framework-simplejwt 进行身份验证。发送的数据正在被 React 消耗。

到目前为止,我已经能够对 进行子类化,TokenObtainPairSerializer以便在登录/获取新令牌时返回用户名和 ID。

class MyTokenObtainPairSerializer(TokenObtainPairSerializer):
    def validate(self, attrs):
        data = super(MyTokenObtainPairSerializer, self).validate(attrs)

        data.update({'user': self.user.username})
        data.update({'id': self.user.id})

        return data
Run Code Online (Sandbox Code Playgroud)

我试图在刷新令牌时返回用户用户名和 ID。然而,这不起作用:

class MyTokenRefreshSerializer(TokenRefreshSerializer):

    def validate(self, attrs):
        data = super(MyTokenRefreshSerializer, self).validate(attrs)
        user = self.context['request'].user
        data.update({'user': user.username})
        data.update({'id': user.id})

        return data  
Run Code Online (Sandbox Code Playgroud)

此处,用户名始终以空字符串形式返回,ID 始终以 null 形式返回。

我尝试了许多不同的方法,包括尝试在视图本身中更新此信息,但似乎无法使其正常工作。我注意到TokenObtainPairSerializer 子类TokenRefreshSerializer本身使用 Django 身份验证对用户进行身份验证。这似乎需要密码(就像用户登录时一样),但显然在简单刷新令牌时不会提供密码。serializers.SerializerTokenObtainSerializer

我的问题是,刷新令牌时如何返回当前用户的用户名和 ID(或任何任意信息)?

后续问题是,当用户首次登录时简单地将这些信息保存到前端的 localStorage 并让状态在每次后续访问时重新填充该数据(直到用户注销,或者刷新令牌不再有效)?

请注意:这不是类似问题的重新发布因为我的目标是刷新令牌。最初的TokenObtainPairView子类化和实现很简单。

authentication django jwt django-rest-framework django-rest-framework-simplejwt

6
推荐指数
1
解决办法
4068
查看次数

简单的 JWT 向令牌中的有效负载数据添加额外的字段

我使用 djoser 和 rest_framework_simplejwt。这是我的用户模型;

class userProfile(models.Model):

    user=models.OneToOneField(User,on_delete=models.CASCADE,related_name="profile")
    date_joined=models.DateTimeField(auto_now_add=True)
    updated_on=models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.user.username
Run Code Online (Sandbox Code Playgroud)

我的 views.py 为用户获取令牌在下面给出;

class CustomTokenObtainPairView(TokenObtainPairView):

serializer_class = CustomTokenObtainPairSerializer
token_obtain_pair = TokenObtainPairView.as_view()
Run Code Online (Sandbox Code Playgroud)

这是serializer.py;

class CustomTokenObtainPairSerializer(TokenObtainPairSerializer):
def validate(self, attrs):
    data = super(CustomTokenObtainPairSerializer, self).validate(attrs)
    data.update({'user': self.user.username})
    data.update({'id': self.user.id})
    data.update({'first_name': self.user.first_name})
    data.update({'last_name': self.user.last_name})
    data.update({'is_superuser': self.user.is_superuser})
    return data
Run Code Online (Sandbox Code Playgroud)

我可以像这样获得访问和刷新令牌。

    {
    "refresh": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImV4cCI6MTU4ODQxMDY0OCwianRpIjoiNTY2MDhhOGVjYzRiNDZhMmFjYjc0Y2VmMzE2ZGE4YTkiLCJ1c2VyX2lkIjo3fQ.gXk9y3Vq0NlB8ZpU9SFcLWAMplr4_ECTeBg5WTMAuNY",
    "access": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNTg4NDA5NzQ4LCJqdGkiOiIxM2VlYzQ1MjZkMTQ0ODI4YjgxNjVkZTA0MzlmYjBmMSIsInVzZXJfaWQiOjd9.sQ1G3rur1h3yqj79ZYvzHK1o6mgtHYuzJZlh5OCyg84",
    "user": "x",
    "id": 5,
    "first_name": "x",
    "last_name": "x",
    "is_superuser": false,

}
Run Code Online (Sandbox Code Playgroud)

当使用 jwt.io 有效载荷数据编码令牌时;

{
  "token_type": "access",
  "exp": 1588329561,
  "jti": "944f97343b42448fbaf5461295eb0548",
  "user_id": 5
}
Run Code Online (Sandbox Code Playgroud)

我想在访问令牌的有效负载中添加用户 first_name、last_name 和 ? …

django djoser django-rest-framework-simplejwt

6
推荐指数
1
解决办法
2355
查看次数

我如何使用简单 JWT 进行自定义用户模型

我正在管理我的用户模型(针对客户),但我不知道如何将 simple-jwt 用于我的客户模型及其自定义登录视图。

模型.py

from django.db import models

class Customer(models.Model):
   name = models.CharField(max_length=100)
   email = models.EmailField(max_length=100)
   password = models.CharField(max_length=100)
Run Code Online (Sandbox Code Playgroud)

另外,我想通过保存刷新令牌来管理我的客户会话,任何人都可以告诉我如何实现这一目标。

django-rest-framework django-rest-framework-jwt django-rest-framework-simplejwt

6
推荐指数
1
解决办法
1万
查看次数

DRF 壮观未发现自定义身份验证扩展类

当从rest_framework_simplejwt.authentication.JWTAuthentication drf-spectaulous swagger-ui 授权按钮扩展新的令牌身份验证类时,授权按钮消失并且无法添加令牌承载者,我想当您子类化时它会出错。
重现步骤:
首先,创建一个 Django 项目,其中安装有 Rest Framework 和 drf-spectaulous 以及简单的 jwt,并按照文档指导进行配置。到达 /swagger-ui/ ,它工作正常。
然后创建 JWTAuthentication 的子类,如下所示:

from rest_framework_simplejwt.authentication import JWTAuthentication as JWTA

class JWTAuthentication(JWTA):
    pass
Run Code Online (Sandbox Code Playgroud)

并在您的设置中:

REST_FRAMEWORK = {
    'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'path_to_your_module.JWTAuthentication',
    ),
}
Run Code Online (Sandbox Code Playgroud)

现在,如果您转到 /swagger-ui/ ,则没有授权按钮!!! 我怎样才能解决这个问题?
我什至尝试创建一个 AuthenticationExtension ,例如:

from drf_spectacular.contrib.rest_framework_simplejwt import SimpleJWTScheme

class SimpleJWTTokenUserScheme(SimpleJWTScheme):
    target_class = 'path_to_your_module.JWTAuthentication'
Run Code Online (Sandbox Code Playgroud)

但无法在任何地方、互联网上或文档中注册它!覆盖身份验证类时如何修复授权按钮?
编辑:按照 JPG 所说的操作并在设置中导入扩展名:

# settings.py
from path.to.custom.extension import SimpleJWTTokenUserScheme
REST_FRAMEWORK = {
    'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'path_to_your_module.JWTAuthentication',
    ),
}
Run Code Online (Sandbox Code Playgroud)

引发异常:

  File "/home/hamex/current/spec/env/lib/python3.8/site-packages/django/core/handlers/exception.py", …
Run Code Online (Sandbox Code Playgroud)

django swagger django-rest-framework django-rest-framework-simplejwt drf-spectacular

6
推荐指数
1
解决办法
7747
查看次数

Django Rest Framework 自定义 JWT 认证

我创建了一个 Django 应用程序,我希望在其中不仅可以通过检查用户名和密码,还可以通过检查相关模型中的特定字段来对用户进行身份验证。我想发送POST到端点的自定义请求正文是:

payload = { 'username': user, 'password': password, 'app_id': uuid4}
Run Code Online (Sandbox Code Playgroud)

我正在使用djangorestframework-simplejwt模块来获取访问令牌。

模型.py

class Application(models.Model):

    app_name  = models.CharField(max_length=300)
    app_id    = models.UUIDField(default=uuid.uuid4, editable=False)

    def __str__(self):
        return self.app_name

class ProfileApp(models.Model):

    user       = models.OneToOneField(User, on_delete=models.CASCADE)
    app        = models.ForeignKey(Application, on_delete=models.CASCADE)
    expires_on = models.DateTimeField(default=datetime.now() + timedelta(days=15))

    def __str__(self):
        return self.app.app_name + " | "  + self.user.username
Run Code Online (Sandbox Code Playgroud)

如果日期仍未过期,是否可以覆盖TokenObtainPairViewfromrest_framework_simplejwt以仅对用户进行身份验证expires_on?或者这样做是否存在架构问题?

python django django-rest-framework django-rest-framework-simplejwt

5
推荐指数
1
解决办法
5037
查看次数

删除特定 url 路径的身份验证和权限

我正在使用 DRF 并遇到了这个问题。我有一个第三方视图,我将其导入到我的urls.py文件中,如下所示:

from some_package import some_view

urlpatterns = [
    path('view/',some_view)
]
Run Code Online (Sandbox Code Playgroud)

但我面临的问题是因为我已经启用了默认权限类,settings.py如下所示:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
               'rest_framework.authentication.TokenAuthentication',
    ),
    'DEFAULT_PERMISSION_CLASSES':(
                'rest_framework.permissions.IsAuthenticated',
    ),

}
Run Code Online (Sandbox Code Playgroud)

现在,当我使用 url 调用该视图时,它给了我身份验证错误,因为我没有提供令牌。有没有办法可以绕过身份验证错误而不必直接更改视图,我知道我们可以删除权限特定视图,但为此我必须对该some_view功能代码进行更改。但我不想这样做,假设我们无权访问该功能,我们只能传递数据并接收响应。如何绕过身份验证而不必更改该功能代码。我尝试搜索,但找不到我要找的东西。

我假设可能有某种方式我们可以从 urls.py 中做到这一点,例如指定任何参数或类似的东西,使该特定视图绕过身份验证而无需更改函数代码。

像这样的东西:

from some_package import some_view

    urlpatterns = [
        path('view/',some_view,"some_parameter") #passing someparameter from here or something like that
    ]
Run Code Online (Sandbox Code Playgroud)

有可能是我在找什么吗?提前致谢 :)

python django django-rest-framework django-rest-auth django-rest-framework-simplejwt

5
推荐指数
1
解决办法
1511
查看次数

如何解码和验证 simple-jwt-django-rest-framework 令牌

我正在尝试验证和解码 simple-jwt-django-rest-framework 令牌。我知道我们可以使用 simple-jwt 的验证 api。但我想在我的观点中解码和验证。以下是我正在尝试的当前代码:-

//in views.py

class home(APIView):
   def post(self,request,*args,**kwargs):
      print("request is ",request._request)
      verify_token_response = token_verify(request._request)
      print("status_code is ", verify_token_response.status_code)

      if(verify_token_response.status_code == 200):
        jwt_object  = JWTAuthentication() 
        validated_token = jwt_object.get_validated_token(request._request)
        user            = jwt_object.get_user(validated_token)
        print(user)
    
    return Response({
            'status':True, 
            'message':'home'
            })
Run Code Online (Sandbox Code Playgroud)

此代码适用于我的令牌验证。它正在正确验证令牌,但是当我检索 valiated_token 和用户时,它给了我以下错误:-

{
    "detail": "Given token not valid for any token type",
    "code": "token_not_valid",
    "messages": [
        {
            "token_class": "AccessToken",
            "token_type": "access",
            "message": "Token is invalid or expired"
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

python django-views django-rest-framework django-rest-framework-simplejwt

5
推荐指数
3
解决办法
4262
查看次数

向 DRF 简单 JWT 负载添加声明

使用djangorestframework_simplejwt库,当 POST 到自定义视图时

#urls.py
path('api/token/', MyTokenObtainPairView.as_view(), name='token_obtain'),

#views.py
class MyTokenObtainPairView(TokenObtainPairView):
    serializer_class = MyTokenObtainPairSerializer
Run Code Online (Sandbox Code Playgroud)

我能够获得以下访问令牌

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNTkwOTEwNjg0LCJqdGkiOiI3M2MxYmZkOWNmMGY0ZjI3OTY4MGY0ZjhlYjA1NDQ5NyIsInVzZXJfaWQiOjExfQ.5vs0LmNGseU6rtq3vuQyApupxhQM3FBAoKAq8MUukIBOOYfDAV9guuCVEYDoGgK6rdPSIq2mvcSxkILG8OH5LQ
Run Code Online (Sandbox Code Playgroud)

通过访问https://jwt.io/我可以看到当前有效负载

{
  "token_type": "access",
  "exp": 1590910684,
  "jti": "73c1bfd9cf0f4f279680f4f8eb054497",
  "user_id": 11
}
Run Code Online (Sandbox Code Playgroud)

智威汤逊

所以,我们可以看到令牌的第二部分是有效载荷——包含声明。

我已经探索了如何向响应正文添加更多信息,现在想知道如何通过添加iat claim、用户名和今天的日期来自定义有效负载数据。

python django jwt django-rest-framework django-rest-framework-simplejwt

4
推荐指数
2
解决办法
2438
查看次数

检索访问令牌时出错:b'{\n "error": "redirect_uri_mismatch",\n "error_description": "Bad Request"\n}'

尝试使用 Django Rest + allauth + dj-rest-auth 从 Nuxt 应用程序进行身份验证

第一个错误

allauth.socialaccount.models.SocialApp.DoesNotExist:SocialApp 匹配查询不存在。

通过将 SITE_ID = 1 更改为 2 解决了此问题

其次我收到这个错误

Traceback (most recent call last):
      File "C:\Users\xyz\django-env\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
        response = get_response(request)
      File "C:\Users\xyz\django-env\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
        response = self.process_exception_by_middleware(e, request)
      File "C:\Users\xyz\django-env\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
        response = wrapped_callback(request, *callback_args, **callback_kwargs)
      File "C:\Users\xyz\django-env\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
        return view_func(*args, **kwargs)
      File "C:\Users\xyz\django-env\lib\site-packages\django\views\generic\base.py", line 71, in view
        return self.dispatch(request, *args, **kwargs)
      File "C:\Users\xyz\django-env\lib\site-packages\django\utils\decorators.py", line 45, in …
Run Code Online (Sandbox Code Playgroud)

django django-rest-framework django-allauth nuxt.js django-rest-framework-simplejwt

4
推荐指数
1
解决办法
1145
查看次数