当检索到的电子邮件与现有用户的电子邮件匹配时,django allauth facebook重定向到注册?

时间:2014-06-23 03:05:42

标签: django django-allauth

我成功地使用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 = TrueFalse进行了测试,但没有效果。我尝试更改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?

注意:我试过了

更新

  1. 感谢这个answer,我意识到通过Facebook登录将重定向到一个案例中的注册页面:当从Facebook个人资料中检索到的电子邮件与现有用户的emailid匹配时。
  2. 我已更新问题,以便解释上述情况。
  3. 总结问题,这是多个提供商帐户具有相同电子邮件ID并且django-allauth不允许互换登录的情况(如果我使用facebook注册一次,则django-allauth将要求我仅使用Facebook而不是谷歌或任何其他提供商具有相同的电子邮件ID)
  4. 我使用@receiver(pre_social_login)raise ImmediateHttpResponse(查看我的回答)使用有用的链接解决了问题:thisthisone
  5. 谢谢, 阿米特

1 个答案:

答案 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"