![](/img/trans.png)
[英]JWT Authorization multiple role in django rest framework using simple-jwt
[英]Overriding simple-jwt's TokenObtainPairSerializer to implement 2FA
我目前正在嘗試在我的 Django 應用程序中實現 2FA。 我所做的第一件事是修改 UserSerializer class 中的Meta
UserSerializer
以添加兩個字段enabled
(指示是否為用戶啟用了 2FA)和secret_key
(生成 OTP 的密鑰,當他啟用時共享給用戶2FA)。
為了最大限度地修改登錄流程,我修改了發送來生成訪問令牌的表單,以包含一個新字段“otp”。 用戶可以填寫或者不填寫,后台會檢查用戶是否開啟了2FA,如果開啟了OTP是否正確。
如果沒有 2FA,登錄只是一個帶有 body {"username": usr, "password": pwd}
的 POST 請求。 這已成為一個帶有 body {"username": usr, "password": pwd, "otp": otp}
的 POST 請求。 如果用戶用戶尚未啟用 2FA,他只需將opt
字段留空即可。
我的urls.py
看起來像這樣:
path("api/token/", TokenObtainPairView.as_view(), name="token_obtain_pair")
我的想法是重寫 TokenObtainPairView 以適應新的請求。 根據我的發現,我必須更改validate
方法,但我真的不知道如何做到這一點。 我可能必須獲取用戶的enabled
和secret_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 )。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.