gpt4 book ai didi

python - 覆盖 simple-jwt 的 TokenObtainPairSerializer 以实现 2FA

转载 作者:行者123 更新时间:2023-12-05 02:43:38 26 4
gpt4 key购买 nike

我目前正在尝试在我的 Django 应用程序中实现 2FA。我做的第一件事是修改 UserSerializer 类中的 Meta 类以添加两个字段 enabled (指示是否为 2FA 启用用户)和 secret_key(生成 OTP 的 key ,当他启用 2FA 时共享给用户)。

为了尽可能少地修改登录流程,我修改了为生成访问 token 而发送的表单,以包含一个新字段“otp”。用户可以填写或不填写,后台会检查用户是否启用了2FA,如果是,则OTP是否正确。

如果没有 2FA,登录只是一个正文为 {"username": usr, "password": pwd} 的 POST 请求。这已成为一个正文为 {"username": usr, "password": pwd, "otp": otp} 的 POST 请求。如果用户尚未启用 2FA,他只需将 opt 字段留空即可。

我的 urls.py 看起来像这样:

path("api/token/", TokenObtainPairView.as_view(), name="token_obtain_pair")

我的想法是重写 TokenObtainPairView 以适应新的请求。根据我的发现,我必须更改 validate 方法,但我真的不知道该怎么做。我可能必须获取用户的 enabledsecret_key 字段的值(基于用户名)以生成 OTP(如果相关)并根据 otp 字段。问题是,我不知道该怎么做,而且我在 simple-jwt 实现中有点迷失了。

最佳答案

首先,我不会为您的问题提供完整的解决方案,但这可能是一个好的开始。

创建您的自定义 LoginView:

class LoginView(TokenObtainPairView):
serializer_class = LoginSerializer

实现你自己的继承TokenObtainPairSerializer的序列化器:

class LoginSerializer(TokenObtainPairSerializer):
def validate(self, attrs):
# implement your logic here
# data = super().validate(attrs)
return data

更改urls.py

path("api/token/", LoginView.as_view(), name="token_obtain_pair")

这是 TokenObtainSerializer 的样子:

class TokenObtainSerializer(serializers.Serializer):
username_field = User.USERNAME_FIELD

default_error_messages = {
'no_active_account': _('No active account found with the given credentials')
}

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

self.fields[self.username_field] = serializers.CharField()
self.fields['password'] = PasswordField()

def validate(self, attrs):
authenticate_kwargs = {
self.username_field: attrs[self.username_field],
'password': attrs['password'],
}
try:
authenticate_kwargs['request'] = self.context['request']
except KeyError:
pass

self.user = authenticate(**authenticate_kwargs)

if not getattr(login_rule, user_eligible_for_login)(self.user):
raise exceptions.AuthenticationFailed(
self.error_messages['no_active_account'],
'no_active_account',
)

return {}

所以你可以在你自己的序列化器中实现 __init___ 并添加你的 otp 字段并在 validate 方法中实现你想要的逻辑(你可以访问self.user 并检查他是否启用了2FA

关于python - 覆盖 simple-jwt 的 TokenObtainPairSerializer 以实现 2FA,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66815920/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com