我正在尝试使用 allauth 和 rest-auth 在 django 中实现 Google 认证。经过多个小时的研究,我找到的解决方案都在我的项目中无法工作。
我基于一个 Github 问题和一篇文章编写了代码:
- https://github.com/Tivix/django-rest-auth/issues/403
- https://medium.com/@gonzafirewall/google-oauth2-and-django-rest-auth-92b0d8f70575
我还创建了一个带有 Google 客户端 ID 和 客户端秘钥 的社交应用程序对象。
我的 Google 控制台项目设置:
已授权 JavaScript 起源:http://localhost:8000 已授权重定向 URI:http://localhost:8000/api/v1/users/login/google/callback/
我的代码
providers.py:
from allauth.socialaccount.providers.google.provider import GoogleProvider
class GoogleProviderMod(GoogleProvider):
def extract_uid(self, data):
return str(data['sub'])
adapters.py:
:from allauth.socialaccount.providers.google.views import GoogleOAuth2Adapter
from google.auth.transport import requests
from google.oauth2 import id_token
from myproj.users.providers import GoogleProviderMod
class GoogleOAuth2AdapterIdToken(GoogleOAuth2Adapter):
provider_id = GoogleProviderMod.id
def complete_login(self, request, app, token, **kwargs):
idinfo = id_token.verify_oauth2_token(token.token, requests.Request(), app.client_id)
if idinfo["iss"] not in ["accounts.google.com", "https://accounts.google.com"]:
raise ValueError("Wrong issuer.")
extra_data = idinfo
login = self.get_provider().sociallogin_from_response(request, extra_data)
return login
views.py:
:from allauth.socialaccount.providers.oauth2.client import OAuth2Client
from rest_auth.registration.serializers import SocialLoginSerializer
from rest_auth.registration.views import SocialLoginView
from myproj.users.adapters import GoogleOAuth2AdapterIdToken
class GoogleLoginView(SocialLoginView):
adapter_class = GoogleOAuth2AdapterIdToken
callback_url = "http://localhost:8000/api/v1/users/login/google/callback/"
client_class = OAuth2Client
serializer_class = SocialLoginSerializer
urls.py:
:from allauth.socialaccount.providers.oauth2.views import OAuth2CallbackView
from django.urls import path
from myproj.users.adapters import GoogleOAuth2AdapterIdToken
from myproj.users.views import GoogleLoginView
app_name = "users"
urlpatterns = [
path(
"login/google/",
GoogleLoginView.as_view(),
name="google_login"
),
path(
"login/google/callback/",
OAuth2CallbackView.adapter_view(GoogleOAuth2AdapterIdToken),
name="google_callback"
),
]
settings.py:
:AUTHENTICATION_BACKENDS = [
"django.contrib.auth.backends.ModelBackend",
"allauth.account.auth_backends.AuthenticationBackend",
]
ACCOUNT_DEFAULT_HTTP_PROTOCOL = "http"
当我在登录页面将从Google“登录”按钮返回的ID令牌作为代码参数传递时,发生错误:
allauth.socialaccount.providers.oauth2.client.OAuth2Error: Error retrieving access token: b'{\n "error": "invalid_grant",\n "error_description": "Malformed auth code."\n}'
响应代码为400。
实际上,即使我将一些随机文本传递给代码,错误也是相同的。
感谢帮助!