我正在使用 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
我使用 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
我使用 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 和 ? …
我正在管理我的用户模型(针对客户),但我不知道如何将 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
当从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
我创建了一个 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
我正在使用 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
我正在尝试验证和解码 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
使用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
尝试使用 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
django-rest-framework-simplejwt ×10
django ×8
python ×5
jwt ×2
django-views ×1
djoser ×1
nuxt.js ×1
swagger ×1