You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
BUG: SocialLoginSerializer.validate() checks if email exists, however complete_social_login from allauth already created the user, always ending up in error state
#650
Not signed up user has to login twice before actually logged in.
The first time a user logs in always results in a ValidationError with message 'User is already registered with this e-mail address.'. However the user is actually created in de db, even though the error occurs. If the user logs in again, it recognises the user in the database and logs you in with status 200 (i.e. user is actually logged in).
Issue
SocialLoginSerializer.validate(..) itself checks if the e-mail adress is already in use on signup, however prior to that is call the all-auth function complete_social_login which already checks this, and saves the user:
# /dj_rest_auth/registration/serializers.pyclassSocialLoginSerializer(serializers.Serializer):
defvalidate(self, attrs):
...
ret=complete_social_login(request, login)
########### START callstack into allauth ############ /allauth/socialaccount/helpers.pydefcomplete_social_login(request, sociallogin):
...
flows.login.complete_login(request, sociallogin)
# /allauth/socialaccount/internal/flows/login.pydefcomplete_login(request, sociallogin, raises=False):
...
return_authenticate(request, sociallogin)
def_authenticate(request, sociallogin):
...
ret=process_signup(request, sociallogin)
# /allauth/socialaccount/internal/flows/signup.pydefprocess_signup(request, sociallogin):
...
# Here the user get's saved by allauth, and returns to where dj-rest-auth's SocialLoginSerializer.validate# called complete_social_login (where it goes wrong.)get_adapter().save_user(request, sociallogin, form=None)
########### END callstack into allauth ############ /dj_rest_auth/registration/serializers.pyclassSocialLoginSerializer(serializers.Serializer):
defvalidate(self, attrs):
...
# Back in dj-rest-auth validation, it tries to validate if the email adress is unique, however# the user was just created by all-auth with exactly this email adress, so it will throw an error# that the adres is already in use. As the user is already created, a new login follows the login flow# instead of the signup flow, and therefore the user can login without issue on the second loginaccount_exists=get_user_model().objects.filter(
email=login.user.email,
).exists()
Possible solution
The returned login variable login.is_existing is checked to see if a user already existed, if not it goes and checks the email adress. However login.user can also be checked, as allauth fills login.user with the created user object on signup, dj-rest-auth could check this and see if it already has an ID. If it has an ID it knows the user is already created (and then assume allauth did proper validation) and hence skip the email check.
Workaround (hacky)
Create a custom SocialLoginSerializer, copy only yhe validate function from the original code and comment out the email check.
# custom_social_login_serializer.pyclassCustomSocialLoginSerializer(SocialLoginSerializer):
defvalidate(self, attrs):
...
# if allauth_account_settings.UNIQUE_EMAIL:# # Do we have an account already with this email address?# account_exists = get_user_model().objects.filter(# email=login.user.email,# ).exists()# if account_exists:# raise serializers.ValidationError(# _('User is already registered with this e-mail address.'),# )# social_providers.pyfromdj_rest_auth.registration.viewsimportSocialLoginViewfromallauth.socialaccount.providers.google.viewsimportGoogleOAuth2Adapterfromallauth.socialaccount.providers.oauth2.clientimportOAuth2Clientfrom .custom_social_login_serializerimportCustomSocialLoginSerializerclassGoolgeAuth(SocialLoginView):
adapter_class=GoogleOAuth2Adapterclient_class=OAuth2Clientserializer_class=CustomSocialLoginSerializer
The text was updated successfully, but these errors were encountered:
Config
Using all-auth social login with Google
Using the following settings:
Functional Issue
Not signed up user has to login twice before actually logged in.
The first time a user logs in always results in a ValidationError with message
'User is already registered with this e-mail address.'
. However the user is actually created in de db, even though the error occurs. If the user logs in again, it recognises the user in the database and logs you in with status 200 (i.e. user is actually logged in).Issue
SocialLoginSerializer.validate(..)
itself checks if the e-mail adress is already in use on signup, however prior to that is call the all-auth functioncomplete_social_login
which already checks this, and saves the user:SocialLoginSerializer.validate(...) calls allauth's complete_social_login
Possible solution
The returned login variable
login.is_existing
is checked to see if a user already existed, if not it goes and checks the email adress. Howeverlogin.user
can also be checked, as allauth fillslogin.user
with the created user object on signup, dj-rest-auth could check this and see if it already has an ID. If it has an ID it knows the user is already created (and then assume allauth did proper validation) and hence skip the email check.Workaround (hacky)
Create a custom SocialLoginSerializer, copy only yhe validate function from the original code and comment out the email check.
The text was updated successfully, but these errors were encountered: