Django中如何通过Google API客户端为安卓端实现账号注册登录
Django 安卓端谷歌登录后端代码修改方案
问题原因
你此前仅为视图类添加了相关属性,但没有调用django-allauth内置的社交账号匹配、用户创建、登录流程逻辑,因此无法生成认证密钥。
完整修改代码
from django.contrib.auth import get_user_model from rest_framework.views import APIView from rest_framework.permissions import AllowAny from rest_framework.response import Response from rest_framework.authtoken.models import Token from google.oauth2 import id_token from google.auth.transport import requests from allauth.socialaccount.models import SocialAccount, SocialLogin from allauth.socialaccount.helpers import complete_social_login from allauth.socialaccount.adapter import get_adapter User = get_user_model() # 此处填写安卓端的谷歌OAuth客户端ID,多个ID可用列表传递 CLIENT_ID = "你的安卓端谷歌客户端ID" class GoogleClientView(APIView): permission_classes = [AllowAny] def post(self, request): id_token_str = request.data.get('id_token') if not id_token_str: return Response({'message': '缺少id_token参数'}, status=400) try: # 验证id_token合法性 idinfo = id_token.verify_oauth2_token( id_token_str, requests.Request(), CLIENT_ID ) if idinfo['iss'] not in ['accounts.google.com', 'https://accounts.google.com']: raise ValueError('Wrong issuer.') # 1. 构造社交登录对象 sociallogin = SocialLogin() # 2. 匹配/创建用户 user = User.objects.filter(email=idinfo['email']).first() if not user: user = User( email=idinfo['email'], first_name=idinfo.get('given_name', ''), last_name=idinfo.get('family_name', ''), is_active=True ) # 若你的用户模型有username等必填字段,请在此处赋值 # user.username = idinfo['email'].split('@')[0] user.save() else: # 可选:更新老用户的信息 user.first_name = idinfo.get('given_name', user.first_name) user.last_name = idinfo.get('family_name', user.last_name) user.save() sociallogin.user = user # 3. 关联社交账号信息 social_account, created = SocialAccount.objects.get_or_create( provider='google', uid=idinfo['sub'], defaults={ 'user': user, 'extra_data': idinfo } ) if not created: social_account.extra_data = idinfo social_account.save() sociallogin.account = social_account # 4. 执行allauth完整登录流程 complete_social_login(request, sociallogin) # 5. 生成认证密钥,以下两种二选一 # 方案1:使用DRF默认TokenAuthentication token, _ = Token.objects.get_or_create(user=user) return_data = { 'token': token.key, 'user_id': user.pk, 'email': user.email } # 方案2:使用JWT认证,需确保已安装dj-rest-auth并开启JWT支持 # from dj_rest_auth.utils import jwt_encode # access_token, refresh_token = jwt_encode(user) # return_data = { # 'access_token': str(access_token), # 'refresh_token': str(refresh_token), # 'user_id': user.pk, # 'email': user.email # } return Response(return_data) except ValueError as err: return Response({'message': f'无效token: {str(err)}'}, status=400) except Exception as e: return Response({'message': f'登录失败: {str(e)}'}, status=500)
配置注意事项
- 安卓端的OAuth 2.0客户端ID必须添加到Django Admin后台「社交应用」对应谷歌应用的「客户端ID」字段中,多个ID用逗号分隔即可。
- 建议在
settings.py中添加如下配置,跳过邮箱二次验证:
SOCIALACCOUNT_PROVIDERS = { 'google': { 'VERIFIED_EMAIL': True, 'EMAIL_AUTHENTICATION': True, } }
- 若使用自定义用户模型,需确保必填字段(如username)要么在代码中赋值,要么设置为允许为空。
内容的提问来源于stack exchange,提问作者Inception_K
相关产品推荐
相关产品推荐

