Django-allauth: Мой поток перенаправления после регистрации с помощью Google Auth нарушен, и я не могу понять, почему

#django #django-allauth

#джанго #джанго-аллаут

Вопрос:

Я интегрировал django-allauth с моим приложением Django, но что-то не работает полностью:

Проблема

  • Если пользователь, у которого нет учетной записи в моей базе данных, попытается зарегистрироваться с помощью процесса google allauth, после процесса аутентификации он будет успешно отправлен на домашнюю страницу (за фильтром входа в систему).
  • Однако, если пользователь , у которого уже есть учетная запись в моей базе данных (созданная вручную), попытается войти в систему с помощью аутентификации Google, посетив /accounts/google/login/ ее, после процесса аутентификации она будет отправлена на /accounts/social/signup/ (странную страницу, которая есть у django-allauth). Забавно, что пользователь вошел в систему, и если он попытается получить доступ к домашней странице, он сможет, и все работает. Так что это просто перенаправление, которое нарушено.

Я сузил это до того факта, что электронная почта пользователя уже существует, но с ней не связана социальная учетная запись.

Установка

У меня есть пользовательская модель пользователя, в которой электронная почта является основным уникальным идентификатором пользователя.

 from django.contrib.auth.base_user import BaseUserManager from django.db import models from django.contrib.auth.models import AbstractUser from django.utils.translation import ugettext_lazy as _   class CustomUserManager(BaseUserManager):  """  Custom user model manager where email is the unique identifiers  for authentication instead of usernames.  """  def create_user(self, email, password, **extra_fields):  """  Create and save a User with the given email and password.  """  if not email:  raise ValueError(_('The Email must be set'))  email = self.normalize_email(email)  user = self.model(email=email, **extra_fields)  user.set_password(password)  user.save()  return user   def create_superuser(self, email, password, **extra_fields):  """  Create and save a SuperUser with the given email and password.  """  extra_fields.setdefault('is_staff', True)  extra_fields.setdefault('is_superuser', True)  extra_fields.setdefault('is_active', True)   if extra_fields.get('is_staff') is not True:  raise ValueError(_('Superuser must have is_staff=True.'))  if extra_fields.get('is_superuser') is not True:  raise ValueError(_('Superuser must have is_superuser=True.'))  return self.create_user(email, password, **extra_fields)   class CustomUser(AbstractUser):  username = None  email = models.EmailField(_('email address'), unique=True)   USERNAME_FIELD = 'email'  REQUIRED_FIELDS = []   objects = CustomUserManager()   def __str__(self):  return self.email  

I have an Adapter that I hoped was going to solve my problem but didn’t (so I did something wrong on it)

 class MySocialAccountAdapter(DefaultSocialAccountAdapter):  def pre_social_login(self, request, sociallogin):  user = sociallogin.user  if user.id:  return  try:  # if user exists, connect the account to the existing account and login  customer = CustomUser.objects.get(email=user.email)  sociallogin.state['process'] = 'connect'  #sociallogin.connect(request, user)  perform_login(request, customer, 'none')  except CustomUser.DoesNotExist:  pass  

my settings

 ...  # Application definition  INSTALLED_APPS = [  'django.contrib.admin',  'django.contrib.auth',  'django.contrib.sites',  'django.contrib.contenttypes',  'django.contrib.sessions',  'django.contrib.messages',  'django.contrib.staticfiles',   'allauth',  'allauth.account',  'allauth.socialaccount',  'allauth.socialaccount.providers.google',  'whitenoise.runserver_nostatic', # new ]  MIDDLEWARE = [  #'django.middleware.security.SecurityMiddleware',  'whitenoise.middleware.WhiteNoiseMiddleware',  'django.contrib.sessions.middleware.SessionMiddleware',  'django.middleware.common.CommonMiddleware',  'django.middleware.csrf.CsrfViewMiddleware',  'django.contrib.auth.middleware.AuthenticationMiddleware',  'django.contrib.messages.middleware.MessageMiddleware',  'django.middleware.clickjacking.XFrameOptionsMiddleware', ]   ...   AUTH_PASSWORD_VALIDATORS = [  {  'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',  },  {  'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',  },  {  'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',  },  {  'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',  }, ]    AUTHENTICATION_BACKENDS = [  'django.contrib.auth.backends.ModelBackend',  'allauth.account.auth_backends.AuthenticationBackend',  'guardian.backends.ObjectPermissionBackend', ]  SITE_ID = 3 LOGIN_REDIRECT_URL = '/' ACCOUNT_ADAPTER = 'myusermodel.adapter.MyAccountAdapter'    # Additional configuration settings SOCIALACCOUNT_QUERY_EMAIL = True ACCOUNT_LOGOUT_ON_GET = True ACCOUNT_UNIQUE_EMAIL = True ACCOUNT_EMAIL_REQUIRED = True ACCOUNT_USER_MODEL_USERNAME_FIELD = None ACCOUNT_USERNAME_REQUIRED = False ACCOUNT_AUTHENTICATION_METHOD = 'email' AUTH_USER_MODEL = 'myusermodel.CustomUser'    SOCIALACCOUNT_PROVIDERS = {  'google': {  'SCOPE': [  'profile',  'email',  ],  'AUTH_PARAMS': {  'access_type': 'online',  }  } }  ...   

Ответ №1:

ИСПРАВЛЕНО!

Это мой новый адаптер, все было так просто!

 from allauth.account.adapter import DefaultAccountAdapter from allauth.socialaccount.adapter import DefaultSocialAccountAdapter from django.shortcuts import redirect, reverse from myusermodel.models import CustomUser    class MyAccountAdapter(DefaultAccountAdapter):   def get_login_redirect_url(self, request):  print('I am entering get_login_redirect_url')  if 'team_membership_project_id' in request.session:  parameters = {}  parameters['invitation_id'] = request.session['invitation_id']  path = reverse('action:accept_invitation', urlconf=None, args=None, kwargs=parameters)  return path   path = '/'   return path   def is_open_for_signup(self, request):  """  Checks whether or not the site is open for signups.Next to simply returning True/False you can also intervene the  regular flow by raising an ImmediateHttpResponse. (Comment reproduced from the overridden method.)  """  return True   class MySocialAccountAdapter(DefaultSocialAccountAdapter):  def pre_social_login(self, request, sociallogin):  user = CustomUser.objects.filter(email=sociallogin.user.email).first()  if user and not sociallogin.is_existing:  sociallogin.connect(request, user)