You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何利用Angular返回的Google登录响应在DRF中完成用户注册登录?

如何用DRF处理Google登录响应完成注册与登录?

嘿,你已经搞定了Angular端的Google登录,接下来咱们在DRF里把注册登录的逻辑串起来,一步步来:

1. 先扩展用户模型(可选但推荐)

默认的Django User模型没有社交平台相关的字段,咱们扩展一个自定义用户模型来存储Google返回的社交ID、平台类型、头像链接这些信息:

# your_app/models.py
from django.contrib.auth.models import AbstractUser
from django.db import models

class CustomUser(AbstractUser):
    PROVIDER_CHOICES = (
        ('GOOGLE', 'Google'),
        # 以后加其他社交平台直接在这里加就行
    )
    social_id = models.CharField(max_length=255, blank=True, null=True, unique=True)
    provider = models.CharField(max_length=20, choices=PROVIDER_CHOICES, blank=True, null=True)
    photo_url = models.URLField(blank=True, null=True)

然后在settings.py里指定使用这个自定义模型:

AUTH_USER_MODEL = 'your_app.CustomUser'

2. 验证Google Token的合法性

不能直接信任前端传来的token,必须去Google官方接口验证它的有效性,写个工具函数来做这件事:

# your_app/utils.py
import requests

def verify_google_token(token):
    # Google官方的token验证接口
    verify_url = 'https://oauth2.googleapis.com/tokeninfo'
    response = requests.get(verify_url, params={'id_token': token})
    
    if response.status_code == 200:
        return response.json()
    return None

3. 编写处理社交登录的核心视图

这个视图会接收前端传来的Google登录数据,先验证token,然后判断用户是新用户(注册)还是老用户(登录),最后返回DRF的认证token:

# your_app/views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework.authtoken.models import Token
from .models import CustomUser
from .utils import verify_google_token

class GoogleAuthView(APIView):
    def post(self, request):
        # 拿到前端传来的Google登录数据
        google_data = request.data
        auth_token = google_data.get('authToken')
        provider = google_data.get('provider')

        # 第一步:验证token合法性
        verified_info = verify_google_token(auth_token)
        if not verified_info:
            return Response({'error': '无效的Google令牌'}, status=status.HTTP_400_BAD_REQUEST)
        
        # 额外校验:确保前端传来的邮箱和Google返回的一致,防止篡改
        if verified_info['email'] != google_data.get('email'):
            return Response({'error': '邮箱信息不匹配'}, status=status.HTTP_400_BAD_REQUEST)

        # 第二步:查找用户,不存在则创建(注册)
        try:
            user = CustomUser.objects.get(social_id=google_data.get('id'), provider=provider)
        except CustomUser.DoesNotExist:
            # 创建新用户,用邮箱前缀当用户名(也可以用social_id)
            username = google_data.get('email').split('@')[0]
            # 处理用户名重复的情况(可选)
            if CustomUser.objects.filter(username=username).exists():
                username = f"{username}_{google_data.get('id')[:6]}"
            
            user = CustomUser.objects.create(
                username=username,
                email=google_data.get('email'),
                first_name=google_data.get('name').split()[0],
                last_name=google_data.get('name').split()[-1] if len(google_data.get('name').split())>1 else '',
                social_id=google_data.get('id'),
                provider=provider,
                photo_url=google_data.get('photoUrl'),
                is_active=True  # 社交登录的用户直接激活
            )
            # 因为是社交登录,不需要密码,设置不可用密码
            user.set_unusable_password()
            user.save()

        # 第三步:生成或获取DRF的认证Token,返回给前端
        token, created = Token.objects.get_or_create(user=user)
        return Response({
            'token': token.key,
            'user': {
                'id': user.id,
                'name': user.get_full_name(),
                'email': user.email,
                'photoUrl': user.photo_url,
                'provider': user.provider
            }
        }, status=status.HTTP_200_OK)

4. 配置路由

把刚才写的视图加到路由里:

# your_app/urls.py
from django.urls import path
from .views import GoogleAuthView

urlpatterns = [
    path('auth/google/', GoogleAuthView.as_view(), name='google-auth'),
]

一些额外注意事项

  • 记得安装requests库:pip install requests
  • 如果用DRF的TokenAuthentication,要在settings.py里配置:
    REST_FRAMEWORK = {
        'DEFAULT_AUTHENTICATION_CLASSES': [
            'rest_framework.authentication.TokenAuthentication',
        ],
    }
    
  • 如果你想用JWT代替DRF默认的Token,可以用djangorestframework-simplejwt库,把生成Token的逻辑换成JWT的即可:
    from rest_framework_simplejwt.tokens import RefreshToken
    
    def get_jwt_tokens(user):
        refresh = RefreshToken.for_user(user)
        return {
            'refresh': str(refresh),
            'access': str(refresh.access_token),
        }
    

最后,前端只需要把Google登录得到的JSON数据POST到/auth/google/接口,拿到返回的Token后,后续请求就把Token放在Authorization头里(格式:Token <你的token> 或者JWT的Bearer <你的token>)就行啦!

内容的提问来源于stack exchange,提问作者sujit tiwari

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:52:02