Подтвердить что ты не робот

Django allauth facebook перенаправляет на регистрацию, когда полученное письмо соответствует существующей электронной почте пользователя?

Я успешно могу войти в систему через Google и Facebook, используя Django (1.6.4) и allauth (0.16.1) и Python (2.7) с ожидаемым перенаправлением на settings.LOGIN_REDIRECT_URL в случае, если нет существующего пользователя с адрес электронной почты, полученный от поставщика. Однако, когда уже существует пользователь с тем же адресом электронной почты, что и тот, который был получен от провайдера (fb или goolge), он всегда перенаправляет на страницу /accounts/social/signup/ # = signup с запросом:

Вы собираетесь использовать свою учетную запись Facebook/Google для входа в example.com. В виде пожалуйста, заполните следующую форму:     Электронная почта автоматически заполняется.

Я тестировал с SOCIALACCOUNT_AUTO_SIGNUP = True или False, но никакого эффекта. Я попытался изменить auth_type для facebook, но я не вижу никаких других параметров, кроме "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"

Как я могу остановить это перенаправление для регистрации и переадресовать логин провайдера в LOGIN_REDIRECT_URL в конкретном случае уже существующего пользователя с тем же адресом электронной почты?

ПРИМЕЧАНИЕ. Это я пробовал

ОБНОВЛЕНИЕ:

  • Благодаря этому answer, я понял, что логин через facebook будет перенаправлен на страницу регистрации в случае: когда электронная почта, полученная из facebook профили совпадает с уже существующим пользователем электронной почты.
  • Я обновил вопрос, чтобы учесть вышеупомянутый случай.
  • Чтобы суммировать проблему, это случай, когда несколько учетных записей провайдеров имеют одинаковый идентификатор электронной почты, а django-allauth не разрешает взаимозаменяемый логин (ei, если я зарегистрировал один раз с помощью facebook, django-allauth потребует от меня использовать только facebook и не Google или ничего другого провайдера с тем же адресом электронной почты)
  • Я решил это, используя @receiver(pre_social_login) и raise ImmediateHttpResponse (посмотрите на мой ответ) с полезными ссылками: this и thisone

Спасибо, Amit

4b9b3361

Ответ 1

Я решил его после копания в глубине google и исходного кода django и django-allauth

Проблема решается: Я просто хочу, способность к взаимозаменяемые Войти с помощью Facebook и Google с таким же электронный идентификатор и всегда перенаправлять LOGIN_REDIRECT_URL после успешного входа в систему, но Джанго-allauth не позволяет мне сделать это, Вместо этого он представляет мне страницу регистрации, которую я не хочу.

Решение:. Используйте @receiver(pre_social_login) для вызова функции link_to_local_user(), которая регистрируется в 1-м, а затем поднимает 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 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"