覆盖 allauth 的 account/login.html
模板并呈现 Google 按钮(记得替换 <GOOGLE_APP_CLIENT_ID>
和 <HOMEPAGE>
):
<div class="g_id_signin" data-type="standard" data-shape="pill"
data-theme="outline" data-text="signin_with" data-size="large"
data-logo_alignment="left"></div>
<div id="g_id_onload"
data-client_id="<GOOGLE_APP_CLIENT_ID>"
data-context="signin"
data-ux_mode="redirect"
data-login_uri="<HOMEPAGE>{% url 'google-login' %}?next={{ request.GET.next }}"
data-auto_prompt="false"></div>
<script src="https://accounts.google.com/gsi/client" async defer></script>
如果您还没有安装,可以安装 google-auth
:
pip install google-auth
在你的urls.py
中注册google-login
端点:
path('google-login', views.google_login, name='google-login'),
在你的views.py
中定义google-login
端点,在重定向到allauth
的Google登录URL之前,验证Google ID令牌:
import logging
from django.conf import settings
from django.contrib import messages
from django.http import HttpResponseBadRequest
from django.shortcuts import redirect
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_POST
from google.oauth2 import id_token
from google.auth.transport import requests
from urllib import parse
@csrf_exempt
@require_POST
def google_login(request):
body_unicode = request.body.decode('utf-8')
body_params = parse.parse_qs(body_unicode)
csrf_token_cookie = request.COOKIES.get('g_csrf_token')
if not csrf_token_cookie:
return HttpResponseBadRequest('No CSRF token in Cookie.')
csrf_token_body = body_params.get('g_csrf_token')
if not csrf_token_body:
return HttpResponseBadRequest('No CSRF token in post body.')
if csrf_token_cookie != csrf_token_body[0]:
return HttpResponseBadRequest('Failed to verify double submit cookie.')
next_url = request.GET['next']
try:
token = body_params.get('credential')[0]
idinfo = id_token.verify_oauth2_token(token, requests.Request(), settings.GOOGLE_APP_CLIENT_ID)
except ValueError as e:
logging.error(e)
return HttpResponseBadRequest('Failed to verify Google auth credentials.')
return redirect(settings.HOMEPAGE + '/accounts/google/login/?next=' + next_url)