Django集成allauth与dj_rest_auth登录失败问题求助
向http://127.0.0.1:8000/api/auth/login/发送POST请求时遇到异常:当INSTALLED_APPS包含'allauth'时,登录接口返回认证失败错误,但我需要allauth实现谷歌第三方登录;移除'allauth'后,登录功能完全正常。请求体中的邮箱和密码确认是正确的,求解决思路。
API响应:
{ "non_field_errors": [ "Unable to log in with provided credentials." ] }
后端日志:
Bad Request: /api/auth/login/ [17/Oct/2024 09:56:13] "POST /api/auth/login/ HTTP/1.1" 400 68
请求体:
{ "email":"test@mail.com", "password":"******" }
urls.py代码:
from django.contrib import admin from django.urls import include, path, re_path from django.conf.urls.static import static from django.conf import settings from allauth.account.views import ConfirmEmailView from accounts.views import GoogleLogin, GoogleLoginCallback urlpatterns = [ path('admin/', admin.site.urls), path('api/', include('app.urls')), path("api/auth/", include("dj_rest_auth.urls")), re_path( r"^api/auth/registration/account-confirm-email/(?P<key>[-:\w]+)/$", ConfirmEmailView.as_view(), name="account_confirm_email", ), path('api/auth/registration/', include('dj_rest_auth.registration.urls')), path("api/auth/google/", GoogleLogin.as_view(), name="google_login"), path( "api/auth/google/callback/", GoogleLoginCallback.as_view(), name="google_login_callback", ), ] if settings.DEBUG: urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
settings.py代码:
AUTH_USER_MODEL = 'app.CustomUser' MEDIA_URL = '/document/' MEDIA_ROOT = BASE_DIR INSTALLED_APPS = [ 'jazzmin', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'django.contrib.sites', 'corsheaders', 'rest_framework', 'rest_framework.authtoken', 'rest_framework_simplejwt', 'allauth', 'allauth.account', 'allauth.socialaccount', 'allauth.socialaccount.providers.google', 'dj_rest_auth', 'dj_rest_auth.registration', 'app', ] SITE_ID = 1 REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework_simplejwt.authentication.JWTAuthentication', ) } SIMPLE_JWT = { "ACCESS_TOKEN_LIFETIME": timedelta(hours=1), "REFRESH_TOKEN_LIFETIME": timedelta(days=1), } REST_AUTH = { "USE_JWT": True, "JWT_AUTH_HTTPONLY": False, } MIDDLEWARE = [ 'corsheaders.middleware.CorsMiddleware', 'django.middleware.security.SecurityMiddleware', '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', "allauth.account.middleware.AccountMiddleware", ] ACCOUNT_AUTHENTICATION_METHOD = "email" ACCOUNT_USERNAME_REQUIRED = False ACCOUNT_EMAIL_REQUIRED = True ACCOUNT_EMAIL_VERIFICATION = "none" EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend" EMAIL_HOST = "smtp.gmail.com" EMAIL_PORT = 587 EMAIL_USE_TLS = True EMAIL_HOST_USER = os.getenv("EMAIL_HOST_USER") EMAIL_HOST_PASSWORD = os.getenv("EMAIL_HOST_PASSWORD") ACCOUNT_EMAIL_VERIFICATION = "mandatory" ACCOUNT_CONFIRM_EMAIL_ON_GET = True LOGIN_URL = "/admin" GOOGLE_OAUTH_CLIENT_ID = os.getenv("GOOGLE_OAUTH_CLIENT_ID") GOOGLE_OAUTH_CLIENT_SECRET = os.getenv("GOOGLE_OAUTH_CLIENT_SECRET") GOOGLE_OAUTH_CALLBACK_URL = os.getenv("GOOGLE_OAUTH_CALLBACK_URL") SOCIALACCOUNT_EMAIL_AUTHENTICATION = True SOCIALACCOUNT_EMAIL_AUTHENTICATION_AUTO_CONNECT = True SOCIALACCOUNT_PROVIDERS = { "google": { "APPS": [ { "client_id": GOOGLE_OAUTH_CLIENT_ID, "secret": GOOGLE_OAUTH_CLIENT_SECRET, "key": "", }, ], "SCOPE": ["profile", "email"], "AUTH_PARAMS": { "access_type": "online", }, } }
统一邮箱验证配置:你的settings里重复设置了
ACCOUNT_EMAIL_VERIFICATION,先设为"none"又改成"mandatory",最终生效的是强制验证规则。如果测试用户的邮箱未完成验证,allauth会直接阻止登录。先把该配置统一设为"none"测试,确认是否是验证环节导致的问题。检查CustomUser模型:确认你的CustomUser是否正确继承
AbstractUser,且邮箱字段设置了unique=True。allauth的认证逻辑依赖唯一邮箱标识用户,若邮箱字段不唯一,会导致凭证匹配失败。排查中间件干扰:allauth的
AccountMiddleware可能修改了认证上下文,导致dj_rest_auth的默认登录逻辑无法正确获取用户。可以临时注释掉该中间件测试,若恢复正常,再针对性调整中间件顺序或逻辑。验证数据库迁移状态:安装allauth后需确保相关表已正确生成,运行
python manage.py makemigrations和python manage.py migrate,避免因表缺失导致认证流程异常。调试认证流程:在dj_rest_auth的登录视图中添加日志,打印用户查找过程,确认allauth是否拦截了凭证验证步骤,或者是否存在用户状态(如是否激活)的判断冲突。
内容的提问来源于stack exchange,提问作者luca Beru

