Reputation: 1182
Does anyone know how I would go about bypassing the signup page when using a social account in django allauth?
I've got the authentication side of things working with Google but when the user accepts the request from Google, it redirects to a page which asks them to enter their email address before they can log in.
But surely it will have retrieved this information from the Google login and should be able to simply log the user in so that they can use the site?
How would I go about doing that?
Thanks.
Upvotes: 11
Views: 2923
Reputation: 1
I would definitely not suggest using SOCIALACCOUNT_LOGIN_ON_GET=True for bypassing the first intermediate default sign in page from django allauth templates as it is not a recommended method due to CSRF Vulnerability and other threats.
Rather, prefer using method="POST" on the login/signup form to authenticate with Google or any other providers. implement the following in your templates/login.html.
<form method="POST">
{% csrf_token %}
<a href="{% provider_url_login 'google' %}">
Login with Google
</a>
</form>
This will totally bypass the first intermediate default sign in page from django allauth templates as follow:
https://i.sstatic.net/8MXBZl1T.png
If you use a custom login/signup form for google authentication in your django template, you can bypass the default signup template and skip the email and user authentication form provided by default django-allauth template by using custom adapter.
Just create an "adapter.py" file in your django application inside your project as myproject/myapp/adapter.py and add the following inside your "adapter.py".
import logging
from django.conf import settings
from allauth.socialaccount.adapter import DefaultSocialAccountAdapter
from django.contrib.auth import get_user_model
User = get_user_model()
class MyAccountAdapter(DefaultSocialAccountAdapter):
def pre_social_login(self, request, sociallogin):
user = User.objects.filter(email=sociallogin.user.email).first()
if user and not sociallogin.is_existing:
sociallogin.connect(request, user)
Also, make sure to add your adapter in settings.py as:
SOCIALACCOUNT_ADAPTER='myapp.adapter.MyAccountAdapter'
This should work for the following issue:
https://i.sstatic.net/98Jp29KN.png
And there you go, you just bypassed two annoying default django-allauth intermediate Sign in & Signup pages in a secure way. Rest of the things, make sure you made your Google OAuth2 configurations and settings correct in your django project and you're good to go.
Upvotes: 0
Reputation: 7222
If you redirect the user to
{% provider_login_url 'google' %}
and allauth shows the user an intermediate page with
You are about to sign in using a third party account from Google.
when there is no other user associated with the same email address, then you need to add this configuration to bypass the intermediate page:
SOCIALACCOUNT_LOGIN_ON_GET=True
This was added in version 0.47.0, because of a potential vulnerability described in the change notes:
Automatically signing in users into their account and connecting additional third party accounts via a simple redirect ("/accounts/facebook/login/") can lead to unexpected results and become a security issue especially when the redirect is triggered from a malicious web site. For example, if an attacker prepares a malicious website that (ab)uses the Facebook password recovery mechanism to first sign into his/her own Facebook account, followed by a redirect to connect a new social account, you may end up with the attacker's Facebook account added to the account of the victim. To mitigate this, SOCIALACCOUNT_LOGIN_ON_GET is introduced.
I realise this is answering a slightly different question, because in this case the user isn't confirming an email, but it's related, because the user still doesn't directly sign up/log in.
Upvotes: 8
Reputation: 187
Simple solution is to add
SOCIALACCOUNT_LOGIN_ON_GET=True
to your settings.py and it should skip/bypass the sign up form.
Upvotes: 8
Reputation: 203
This is an old question with many views, but I faced the same issue today and thought I would share my solution.
The key to resolving this is to follow the django-allauth 'Advanced Usage' docs, with the example presented by the custom redirects: https://django-allauth.readthedocs.io/en/latest/advanced.html#custom-redirects
Except in this instance, what you need to configure is the SOCIALACCOUNT_ADAPTER in settings.py with a subclassed DefaultSocialAccountAdapter, overriding the 'pre_social_login' method as such:
from allauth.socialaccount.adapter import DefaultSocialAccountAdapter
from django.conf import settings
from django.contrib.auth import get_user_model
User = get_user_model()
class CustomSocialAccountAdapter(DefaultSocialAccountAdapter):
"""
Override the DefaultSocialAccountAdapter from allauth in order to associate
the social account with a matching User automatically, skipping the email
confirm form and existing email error
"""
def pre_social_login(self, request, sociallogin):
user = User.objects.filter(email=sociallogin.user.email).first()
if user and not sociallogin.is_existing:
sociallogin.connect(request, user)
'pre_social_login' is not super well documented, but in the source is a docstring which will help: https://github.com/pennersr/django-allauth/blob/master/allauth/socialaccount/adapter.py
Upvotes: 4
Reputation: 4593
You need to explicitly define the 'email' scope for google in your SOCIALACCOUNT_PROVIDERS settings
'google': { 'SCOPE': ['https://www.googleapis.com/auth/userinfo.profile', 'https://www.googleapis.com/auth/userinfo.email'],
'AUTH_PARAMS': { 'access_type': 'online' },
}
Upvotes: -2