Skip to content

Instantly share code, notes, and snippets.

@squio
Created October 25, 2021 15:43
Show Gist options
  • Save squio/bbc152c3fc8120773fc90e34f6469fe4 to your computer and use it in GitHub Desktop.
Save squio/bbc152c3fc8120773fc90e34f6469fe4 to your computer and use it in GitHub Desktop.
Add 2fa authentication to dj_rest_auth login
# in settings.py
REST_AUTH_SERIALIZERS = {
# override dj_rest_auth serializer for 2fa
'LOGIN_SERIALIZER': 'my_app.serializers.user.LoginSerializer'
}
# my_app.serializers.user
from dj_rest_auth.serializers import LoginSerializer as BaseLoginSerializer
from rest_framework import exceptions, serializers
from django_otp import match_token as match_otp_token
from django_otp import user_has_device as user_has_otp_device
class LoginSerializer(BaseLoginSerializer):
""" Override dj_rest_auth LoginSerializer for 2fa tokens """
otp_token = serializers.CharField(required=False, allow_blank=True)
def validate(self, attrs):
attrs = super().validate(attrs)
user = attrs['user']
if user_has_otp_device(user, confirmed=True):
token = attrs.get('otp_token')
if not token:
attrs['user'] = None
msg = _('Please provide a two factor code to authenticate.')
raise exceptions.NotAcceptable({'otp_token': [msg]})
if match_otp_token(user, token):
return attrs
else:
attrs['user'] = None
msg = _('Invalid two factor code.')
raise exceptions.NotAuthenticated({'otp_token': [msg]})
return attrs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment