配置dj-rest-auth谷歌登录时遇TypeError:get_scope()参数不匹配
Django配置dj-rest-auth谷歌登录报错解决
配置代码
settings.py
INSTALLED_APPS = [ "django.contrib.admin", "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.sessions", "django.contrib.messages", "django.contrib.staticfiles", "corsheaders", "rest_framework", "rest_framework.authtoken", "allauth", "allauth.account", "allauth.socialaccount", "allauth.socialaccount.providers.google", "dj_rest_auth", "dj_rest_auth.registration", ... ] ... REST_AUTH = { "USE_JWT": True, "JWT_AUTH_COOKIE": "access", "JWT_AUTH_REFRESH_COOKIE": "refresh", } REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( 'dj_rest_auth.jwt_auth.JWTCookieAuthentication', ), ... } SOCIALACCOUNT_PROVIDERS = { "google": { "EMAIL_AUTHENTICATION": True, "FETCH_USER_INFO": True, "SCOPE": ["profile", "email"], "APP": { "client_id": "my-client-id", "secret": "my-secret", }, "AUTH_PARAMS": { "access_type": "online", } } } ...
views.py
from allauth.socialaccount.providers.google.views import GoogleOAuth2Adapter from allauth.socialaccount.providers.oauth2.client import OAuth2Client from dj_rest_auth.registration.views import SocialLoginView class GoogleLogin(SocialLoginView): adapter_class = GoogleOAuth2Adapter callback_url = "http://localhost:8000/auth/google/callback" client_class = OAuth2Client def get_serializer(self, *args, **kwargs): serializer_class = self.get_serializer_class() kwargs["context"] = self.get_serializer_context() return serializer_class(*args, **kwargs)
urls.py
from django.urls import path, include from .views import GoogleLogin urlpatterns = [ path("", include("dj_rest_auth.urls")), path("google/", GoogleLogin.as_view(), name="google"), path("registration/", include("dj_rest_auth.registration.urls")), ]
(上述配置路由前缀为/auth/)
报错信息
POST请求到/auth/google/时触发内部服务器错误:
Internal Server Error: /auth/google/ Traceback (most recent call last): File "/home/gl/.cache/pypoetry/virtualenvs/vtk_backend-Ry6OzTQz-py3.12/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner response = get_response(request) ^^^^^^^^^^^^^^^^^^^^^ File "/home/gl/.cache/pypoetry/virtualenvs/vtk_backend-Ry6OzTQz-py3.12/lib/python3.12/site-packages/django/core/handlers/base.py", line 197, in _get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/gl/.cache/pypoetry/virtualenvs/vtk_backend-Ry6OzTQz-py3.12/lib/python3.12/site-packages/django/views/decorators/csrf.py", line 65, in _view_wrapper return view_func(request, *args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/gl/.cache/pypoetry/virtualenvs/vtk_backend-Ry6OzTQz-py3.12/lib/python3.12/site-packages/django/views/generic/base.py", line 104, in view return self.dispatch(request, *args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/gl/.cache/pypoetry/virtualenvs/vtk_backend-Ry6OzTQz-py3.12/lib/python3.12/site-packages/django/utils/decorators.py", line 48, in _wrapper return bound_method(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/gl/.cache/pypoetry/virtualenvs/vtk_backend-Ry6OzTQz-py3.12/lib/python3.12/site-packages/django/views/decorators/debug.py", line 143, in sensitive_post_parameters_wrapper return view(request, *args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/gl/.cache/pypoetry/virtualenvs/vtk_backend-Ry6OzTQz-py3.12/lib/python3.12/site-packages/dj_rest_auth/views.py", line 48, in dispatch return super().dispatch(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/gl/.cache/pypoetry/virtualenvs/vtk_backend-Ry6OzTQz-py3.12/lib/python3.12/site-packages/rest_framework/views.py", line 509, in dispatch response = self.handle_exception(exc) ^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/gl/.cache/pypoetry/virtualenvs/vtk_backend-Ry6OzTQz-py3.12/lib/python3.12/site-packages/rest_framework/views.py", line 469, in handle_exception self.raise_uncaught_exception(exc) File "/home/gl/.cache/pypoetry/virtualenvs/vtk_backend-Ry6OzTQz-py3.12/lib/python3.12/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception raise exc File "/home/gl/.cache/pypoetry/virtualenvs/vtk_backend-Ry6OzTQz-py3.12/lib/python3.12/site-packages/rest_framework/views.py", line 506, in dispatch response = handler(request, *args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/gl/.cache/pypoetry/virtualenvs/vtk_backend-Ry6OzTQz-py3.12/lib/python3.12/site-packages/dj_rest_auth/views.py", line 125, in post self.serializer.is_valid(raise_exception=True) File "/home/gl/.cache/pypoetry/virtualenvs/vtk_backend-Ry6OzTQz-py3.12/lib/python3.12/site-packages/rest_framework/serializers.py", line 223, in is_valid self._validated_data = self.run_validation(self.initial_data) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/gl/.cache/pypoetry/virtualenvs/vtk_backend-Ry6OzTQz-py3.12/lib/python3.12/site-packages/rest_framework/serializers.py", line 445, in run_validation value = self.validate(value) ^^^^^^^^^^^^^^^^^^^^ File "/home/gl/.cache/pypoetry/virtualenvs/vtk_backend-Ry6OzTQz-py3.12/lib/python3.12/site-packages/dj_rest_auth/registration/serializers.py", line 122, in validate scope = provider.get_scope(request) ^^^^^^^^^^^^^^^^^^^^^^^^^^^ TypeError: OAuth2Provider.get_scope() takes 1 positional argument but 2 were given
自定义GoogleLoginSerializer移除get_scope()的request参数后,出现无提示的400 Bad Request错误。
问题分析
原错误是因为dj-rest-auth的SocialLoginSerializer中调用provider.get_scope(request),但allauth的OAuth2Provider.get_scope()方法仅接受self一个参数,无需传入request,属于依赖版本不兼容问题。
解决方案
方案1:对齐依赖版本
指定兼容的dj-rest-auth和allauth版本,例如:
# poetry配置示例 dj-rest-auth = "3.0.0" django-allauth = "0.58.0"
方案2:自定义序列化器修复参数问题
重写SocialLoginSerializer的validate方法,正确调用get_scope():
# views.py中添加序列化器定义 from dj_rest_auth.registration.serializers import SocialLoginSerializer class GoogleLoginSerializer(SocialLoginSerializer): def validate(self, attrs): attrs = super().validate(attrs) provider = self.adapter.get_provider() # 移除request参数,直接调用get_scope() scope = provider.get_scope() if scope: attrs['scope'] = scope return attrs # 修改GoogleLogin视图使用自定义序列化器 class GoogleLogin(SocialLoginView): adapter_class = GoogleOAuth2Adapter callback_url = "http://localhost:8000/auth/google/callback" client_class = OAuth2Client serializer_class = GoogleLoginSerializer # 添加这行
解决400 Bad Request问题
若自定义序列化器后出现400错误,排查以下点:
- 回调URL匹配:确保谷歌开发者控制台中配置的授权回调URL与
callback_url完全一致(包括HTTP/HTTPS、端口、路径)。 - 请求参数:POST请求需携带
code参数(谷歌授权码),格式为{"code": "your-google-authorization-code"}。 - CSRF配置:前后端分离场景下,需在
settings.py添加:
CSRF_TRUSTED_ORIGINS = ["http://localhost:3000"] # 替换为前端域名
内容的提问来源于stack exchange,提问作者Gilles Lefranc
相关产品推荐
相关产品推荐

