dre*_*c4s 5 python django django-rest-framework django-rest-framework-simplejwt
我创建了一个 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?或者这样做是否存在架构问题?
您可以通过创建一个继承自 的自定义序列化程序TokenObtainPairSerializer并扩展该validate方法以检查自定义字段值来实现此目的。如果您小心地不覆盖父类的必要功能,则不存在体系结构问题。
下面是一个例子:
import datetime as dt
import json
from rest_framework import exceptions
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from rest_framework_simplejwt.views import TokenObtainPairView
class MyTokenObtainPairSerializer(TokenObtainPairSerializer):
def validate(self, attrs):
try:
request = self.context["request"]
except KeyError:
pass
else:
request_data = json.loads(request.body)
username = request_data.get("username")
app_id = request_data.get("app_id")
profile_has_expired = False
try:
profile = ProfileApp.objects.get(user__username=username, app__app_id=app_id)
except ProfileApp.DoesNotExist:
profile_has_expired = True
else:
profile_has_expired = dt.date.today() > profile.expires_on
finally:
if profile_has_expired:
error_message = "This profile has expired"
error_name = "expired_profile"
raise exceptions.AuthenticationFailed(error_message, error_name)
finally:
return super().validate(attrs)
class MyTokenObtainPairView(TokenObtainPairView):
serializer_class = MyTokenObtainPairSerializer
Run Code Online (Sandbox Code Playgroud)
然后在您的 urls 文件中使用MyTokenObtainPairView代替TokenObtainPairView。
此外,由于User并ProfileApp共享一个一对一的字段,看起来您可以完全不使用"app_id" 键/字段。
原始源文件:https : //github.com/davesque/django-rest-framework-simplejwt/blob/04376b0305e8e2fda257b08e507ccf511359d04a/rest_framework_simplejwt/serializers.py
| 归档时间: |
|
| 查看次数: |
5037 次 |
| 最近记录: |