首页 文章

将Django社交身份验证与用户注册同步

提问于
浏览
1

我创建了一个django项目,该项目具有单独的用户注册表单,并使用 python-social-auth 进行直接登录 . 每当我尝试使用我已经用于通过注册表单创建帐户的电子邮件ID的social_auth登录时,已插入单独的行而不是使用现有的行 .

如果我在将电子邮件ID更改为模型中的唯一身份后尝试通过social_auth登录,则会收到错误“电子邮件ID已存在” . 如果我从电子邮件中删除unique,则单独的条目将出现在User表中,并且它被视为不同的帐户 .

现在问题是,我不需要 separate accounts for same email Id (使用注册表格,Facebook,谷歌创建) . 我需要 synchronize the accounts created using registration form and social auth .

Settings.py

import os
import datetime
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
PROJECT_ROOT = os.path.abspath(os.path.dirname(BASE_DIR))

SECRET_KEY = '**********'

DEBUG = True

TEMPLATE_DEBUG = True

ALLOWED_HOSTS = ['*']

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'app.accounts',
    'social.apps.django_app.default',
)

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'social.apps.django_app.middleware.SocialAuthExceptionMiddleware',
)

AUTHENTICATION_BACKENDS = (
    'social.backends.facebook.FacebookOAuth2',
    'social.backends.google.GoogleOAuth2',
    'app.accounts.backends.AuthBackend',
    'django.contrib.auth.backends.ModelBackend',
)
REST_FRAMEWORK = {
    'TEST_REQUEST_DEFAULT_FORMAT': 'json',
    'DEFAULT_RENDERER_CLASSES': (
        'rest_framework.renderers.JSONRenderer',
    ),
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
        'rest_framework.permissions.AllowAny',
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.BasicAuthentication',
    )
}

JWT_AUTH = {
    'JWT_EXPIRATION_DELTA': datetime.timedelta(days=14)
}
JWT_ALLOW_REFRESH = True

TEMPLATE_CONTEXT_PROCESSORS = (
    'django.contrib.auth.context_processors.auth',
    'django.core.context_processors.debug',
    'django.core.context_processors.i18n',
    'django.core.context_processors.media',
    'django.core.context_processors.static',
    'django.core.context_processors.tz',
    'django.core.context_processors.request',
    'django.core.context_processors.csrf',
    'django.contrib.messages.context_processors.messages',
    'social.apps.django_app.context_processors.backends',
    'social.apps.django_app.context_processors.login_redirect',
)


AUTH_USER_MODEL = 'accounts.Account'

ROOT_URLCONF = 'main.urls'

WSGI_APPLICATION = 'main.wsgi.application'


DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'db',
        'USER': 'root',
        'PASSWORD': 'root',
        'HOST': 'localhost', 
        'PORT': '3306',
    }
}

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True

STATIC_URL = '/static/'

STATIC_ROOT = os.path.join(PROJECT_ROOT, 'static')

TEMPLATE_DIRS = (
     os.path.join(PROJECT_ROOT, 'templates'),
)

STATICFILES_DIRS = (
    os.path.join(PROJECT_ROOT, 'static'),
)

SOCIAL_AUTH_LOGIN_URL = 'accounts/home/'
SOCIAL_AUTH_LOGIN_REDIRECT_URL = 'accounts/home/'


SOCIAL_AUTH_PIPELINE = (
    'social.pipeline.social_auth.social_details',
    'social.pipeline.social_auth.social_uid',
    'social.pipeline.social_auth.auth_allowed',
    'social.pipeline.social_auth.social_user',
    'social.pipeline.user.get_username',
    'social.pipeline.mail.mail_validation',
    'social.pipeline.user.create_user',
    'social.pipeline.social_auth.load_extra_data',
    )

SOCIAL_AUTH_USER_MODEL='accounts.Account'

追溯

Traceback (most recent call last):
  File "/home/mugesh/.local/lib/python2.7/site-packages/django/core/handlers/base.py", line 149, in get_response
    response = self.process_exception_by_middleware(e, request)
  File "/home/mugesh/.local/lib/python2.7/site-packages/django/core/handlers/base.py", line 147, in get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/mugesh/.local/lib/python2.7/site-packages/django/views/decorators/cache.py", line 57, in _wrapped_view_func
    response = view_func(request, *args, **kwargs)
  File "/home/mugesh/.local/lib/python2.7/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
    return view_func(*args, **kwargs)
  File "/home/mugesh/.local/lib/python2.7/site-packages/social/apps/django_app/utils.py", line 51, in wrapper
    return func(request, backend, *args, **kwargs)
  File "/home/mugesh/.local/lib/python2.7/site-packages/social/apps/django_app/views.py", line 28, in complete
    redirect_name=REDIRECT_FIELD_NAME, *args, **kwargs)
  File "/home/mugesh/.local/lib/python2.7/site-packages/social/actions.py", line 43, in do_complete
    user = backend.complete(user=user, *args, **kwargs)
  File "/home/mugesh/.local/lib/python2.7/site-packages/social/backends/base.py", line 41, in complete
    return self.auth_complete(*args, **kwargs)
  File "/home/mugesh/.local/lib/python2.7/site-packages/social/utils.py", line 229, in wrapper
    return func(*args, **kwargs)
  File "/home/mugesh/.local/lib/python2.7/site-packages/social/backends/oauth.py", line 387, in auth_complete
    *args, **kwargs)
  File "/home/mugesh/.local/lib/python2.7/site-packages/social/utils.py", line 229, in wrapper
    return func(*args, **kwargs)
  File "/home/mugesh/.local/lib/python2.7/site-packages/social/backends/oauth.py", line 396, in do_auth
    return self.strategy.authenticate(*args, **kwargs)
  File "/home/mugesh/.local/lib/python2.7/site-packages/social/strategies/django_strategy.py", line 96, in authenticate
    return authenticate(*args, **kwargs)
  File "/home/mugesh/.local/lib/python2.7/site-packages/django/contrib/auth/__init__.py", line 74, in authenticate
    user = backend.authenticate(**credentials)
  File "/home/mugesh/.local/lib/python2.7/site-packages/social/backends/base.py", line 82, in authenticate
    return self.pipeline(pipeline, *args, **kwargs)
  File "/home/mugesh/.local/lib/python2.7/site-packages/social/backends/base.py", line 85, in pipeline
    out = self.run_pipeline(pipeline, pipeline_index, *args, **kwargs)
  File "/home/mugesh/.local/lib/python2.7/site-packages/social/backends/base.py", line 112, in run_pipeline
    result = func(*args, **out) or {}
  File "/home/mugesh/.local/lib/python2.7/site-packages/social/pipeline/user.py", line 70, in create_user
    'user': strategy.create_user(**fields)
  File "/home/mugesh/.local/lib/python2.7/site-packages/social/strategies/base.py", line 53, in create_user
    return self.storage.user.create_user(*args, **kwargs)
  File "/home/mugesh/.local/lib/python2.7/site-packages/social/storage/django_orm.py", line 60, in create_user
    return cls.user_model().objects.create_user(*args, **kwargs)
  File "/media/mugesh/Extra/STUDIES/Internship/Projects/wedifly/app/accounts/models.py", line 43, in create_user
    return self._create_user(email, first_name, last_name, password, False, False, **extra_fields)
  File "/media/mugesh/Extra/STUDIES/Internship/Projects/wedifly/app/accounts/models.py", line 26, in _create_user
    user.save(using=self._db)
  File "/home/mugesh/.local/lib/python2.7/site-packages/django/contrib/auth/base_user.py", line 74, in save
    super(AbstractBaseUser, self).save(*args, **kwargs)
  File "/home/mugesh/.local/lib/python2.7/site-packages/django/db/models/base.py", line 700, in save
    force_update=force_update, update_fields=update_fields)
  File "/home/mugesh/.local/lib/python2.7/site-packages/django/db/models/base.py", line 728, in save_base
    updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
  File "/home/mugesh/.local/lib/python2.7/site-packages/django/db/models/base.py", line 812, in _save_table
    result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
  File "/home/mugesh/.local/lib/python2.7/site-packages/django/db/models/base.py", line 851, in _do_insert
    using=using, raw=raw)
  File "/home/mugesh/.local/lib/python2.7/site-packages/django/db/models/manager.py", line 122, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/home/mugesh/.local/lib/python2.7/site-packages/django/db/models/query.py", line 1039, in _insert
    return query.get_compiler(using=using).execute_sql(return_id)
  File "/home/mugesh/.local/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 1060, in execute_sql
    cursor.execute(sql, params)
  File "/home/mugesh/.local/lib/python2.7/site-packages/django/db/backends/utils.py", line 79, in execute
    return super(CursorDebugWrapper, self).execute(sql, params)
  File "/home/mugesh/.local/lib/python2.7/site-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "/home/mugesh/.local/lib/python2.7/site-packages/django/db/utils.py", line 95, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "/home/mugesh/.local/lib/python2.7/site-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "/home/mugesh/.local/lib/python2.7/site-packages/django/db/backends/sqlite3/base.py", line 323, in execute
    return Database.Cursor.execute(self, query, params)
IntegrityError: UNIQUE constraint failed: accounts.email

欢迎任何建议或解决方案 . 谢谢,

2 回答

  • 0

    当您使用社交身份验证时,它有单独的表'social_auth_usersocialauth',当您第一次调用登录时它会被填充,社交身份验证工作的方式是,如果它在'social_auth_usersocialauth'中没有条目,它会创建一个新的在其中输入并假设您是第一次登录并创建新用户,这就是再次创建用户的原因 .

    首先使用社交身份验证,并尝试确定您是否第一次注册,如果是这样,请将他带到注册页面,否则它将作为正常登录 .

  • 0

    我认为将 associate_user 添加到 SOCIAL_AUTH_PIPELINE 旨在解决此问题:

    SOCIAL_AUTH_PIPELINE = (
        ...
        'social.pipeline.social_auth.associate_by_email',
        'social.pipeline.user.create_user',
        'social.pipeline.social_auth.associate_user', # <------
        'social.pipeline.social_auth.load_extra_data',
        ...
    )
    

    它应该将 social_user 与通过表单注册创建的现有用户相关联,而不是创建一个全新的用户 .

相关问题