我成功地使用Django(1.6.4)和allauth(0.16.1)以及Python(2.7)通过Google和Facebook登录,预期重定向到settings.LOGIN_REDIRECT_URL,以防现有用户不存在从提供商处检索emailid。但是,当已存在具有与从提供者(fb或goolge)检索到的emailid相同的emailid的用户时,它始终会重定向到/ accounts / social / signup /# = 注册页面,询问:
您即将使用您的Facebook / Google帐户登录example.com。如 最后一步,请填写以下表格: 电子邮件已自动填写。
我已使用SOCIALACCOUNT_AUTO_SIGNUP = True
或False
进行了测试,但没有效果。我尝试更改facebook的auth_type,但除了" rerequest"
我有以下settings.py:
ACCOUNT_AUTHENTICATION_METHOD = "email" # Defaults to username_email
ACCOUNT_USERNAME_REQUIRED = False # Defaults to True
ACCOUNT_EMAIL_REQUIRED = True # Defaults to False
SOCIALACCOUNT_QUERY_EMAIL = ACCOUNT_EMAIL_REQUIRED
SOCIALACCOUNT_AUTO_SIGNUP = True
SOCIALACCOUNT_EMAIL_REQUIRED = False
ACCOUNT_ADAPTER = "myproject.adapter.MyLoginAccountAdapter"
LOGIN_URL = "/"
LOGIN_REDIRECT_URL = "/users/{id}/mytags"
如何停止此重定向到注册,并将提供程序登录重定向到具有相同emailid的现有用户的LOGIN_REDIRECT_URL?
注意:我试过了
更新
@receiver(pre_social_login)
和raise ImmediateHttpResponse
(查看我的回答)使用有用的链接解决了问题:this和thisone 谢谢, 阿米特
答案 0 :(得分:15)
我深入研究django和django-allauth的谷歌和源代码后解决了这个问题
问题正在解决:我只是希望能够以相同的电子邮件ID互换登录使用facebook和google,并在成功登录后始终重定向到LOGIN_REDIRECT_URL,但django-allauth不允许我这样做。相反,它向我提供了一个我不想要的注册页面。
解决方案:使用@receiver(pre_social_login)
调用记录为1st的函数link_to_local_user()
,然后引发ImmediateHttpResponse,然后重定向到LOGIN_REDIRECT_URL
#! myproject.adapter.py
from allauth.account.adapter import DefaultAccountAdapter
from allauth.socialaccount.adapter import DefaultSocialAccountAdapter
from allauth.exceptions import ImmediateHttpResponse
from allauth.socialaccount.signals import pre_social_login
from allauth.account.utils import perform_login
from allauth.utils import get_user_model
from django.http import HttpResponse
from django.dispatch import receiver
from django.shortcuts import redirect
from django.conf import settings
import json
class MyLoginAccountAdapter(DefaultAccountAdapter):
'''
Overrides allauth.account.adapter.DefaultAccountAdapter.ajax_response to avoid changing
the HTTP status_code to 400
'''
def get_login_redirect_url(self, request):
"""
"""
if request.user.is_authenticated():
return settings.LOGIN_REDIRECT_URL.format(
id=request.user.id)
else:
return "/"
class MySocialAccountAdapter(DefaultSocialAccountAdapter):
'''
Overrides allauth.socialaccount.adapter.DefaultSocialAccountAdapter.pre_social_login to
perform some actions right after successful login
'''
def pre_social_login(self, request, sociallogin):
pass # TODOFuture: To perform some actions right after successful login
@receiver(pre_social_login)
def link_to_local_user(sender, request, sociallogin, **kwargs):
''' Login and redirect
This is done in order to tackle the situation where user's email retrieved
from one provider is different from already existing email in the database
(e.g facebook and google both use same email-id). Specifically, this is done to
tackle following issues:
* https://github.com/pennersr/django-allauth/issues/215
'''
email_address = sociallogin.account.extra_data['email']
User = get_user_model()
users = User.objects.filter(email=email_address)
if users:
# allauth.account.app_settings.EmailVerificationMethod
perform_login(request, users[0], email_verification='optional')
raise ImmediateHttpResponse(redirect(settings.LOGIN_REDIRECT_URL.format(id=request.user.id)))
#! settings.py
ACCOUNT_AUTHENTICATION_METHOD = "email" # Defaults to username_email
ACCOUNT_USERNAME_REQUIRED = False # Defaults to True
ACCOUNT_EMAIL_REQUIRED = True # Defaults to False
SOCIALACCOUNT_QUERY_EMAIL = ACCOUNT_EMAIL_REQUIRED
SOCIALACCOUNT_AUTO_SIGNUP = True
SOCIALACCOUNT_EMAIL_REQUIRED = False
ACCOUNT_ADAPTER = "myproject.adapter.MyLoginAccountAdapter"
SOCIALACCOUNT_ADAPTER = 'myproject.adapter.MySocialAccountAdapter'
LOGIN_URL = "/"
LOGIN_REDIRECT_URL = "/users/{id}/mytags"