2016-07-25 71 views
1

我創建了一個django項目,它有單獨的用戶註冊表單,並使用python-social-auth直接登錄。每當我嘗試使用social_auth登錄時,它將使用我已經用於通過註冊表單創建帳戶的電子郵件ID,而不是使用現有帳戶插入單獨的行。同步Django社交授權與用戶註冊

如果我在將模型中唯一的電子郵件ID更改後嘗試通過social_auth登錄,我收到錯誤「電子郵件ID已存在」。如果我刪除了唯一的電子郵件地址,那麼單獨的條目將進入用戶表,並被視爲不同的帳戶。

現在的問題是,我不需要單獨帳戶相同的電子郵件Id(使用註冊表單,Facebook,谷歌創建)。我需要同步使用註冊表和社交認證創建的帳戶

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 

任何建議或解決方案是值得歡迎的。 謝謝

+0

你有什麼作爲你的'AUTH_USER_MODEL'設置? –

+0

我指定了自定義用戶模型。像AUTH_USER_MODEL ='accounts.Account' – Mugesh

+0

你可以顯示你的社交認證應用程序的設置? –

回答

0

我認爲加上associate_userSOCIAL_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相關聯,而不是創造一個全新的用戶。

+0

電子郵件ID是什麼,我需要指定它是唯一的? – Mugesh

+0

我認爲*電子郵件ID *應該是唯一的。您可能需要重新創建數據庫,以便舊行爲不會持續 –

+0

我重新創建了數據庫,並試圖通過註冊表單創建一個新用戶,然後使用具有相同電子郵件ID的social_auth帳戶登錄。我收到以下錯誤。 「IntegrityError at/accounts/complete/google-oauth2/ UNIQUE約束失敗:accounts.email」 – Mugesh

0

當您使用社交身份驗證時,它具有單獨的表「social_auth_usersocialauth」,當您第一次調用登錄名時它會被填充,社交身份驗證以這樣的方式工作,即如果它沒有「social_auth_usersocialauth」它會在其中創建一個新條目,並假定您第一次登錄並創建一個新用戶,這就是爲什麼用戶需要重新創建的原因。

首先使用社交授權,並嘗試確定您是否第一次註冊,如果是這樣,請將其帶到註冊頁面,否則將作爲匿名登錄使用。

+0

是的,它可以做到。但是,如果我們先註冊登記表,然後用社交身份驗證登錄,該怎麼辦?在這種情況下,Social_auth總是嘗試在用戶表中創建一個新行,並且在使用社交身份驗證登錄時會拋出下面的錯誤。 「IntegrityError at/accounts/complete/google-oauth2/ UNIQUE約束失敗:accounts.email」 – Mugesh

+0

@Mugesh其因爲社交授權視角用戶尚未創建,因爲模型'social_auth_usersocialauth未填寫用戶註冊。一旦發現「social_auth_usersocialauth」爲空,它將創建一個新用戶,但根據註冊,它仍然存在,這就是完整性錯誤即將到來的原因。社交認證和註冊也是如此。 – doubleo46

+0

但是,從用戶的角度來看,他/她可能會在使用社交身份驗證登錄之前先使用註冊表單進行註冊。在這種情況下,會出現相同的完整性錯誤那麼,如何解決? – Mugesh