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

如何使用django-allauth对接Google API(Gmail API)实现独立OAuth2授权

如何使用django-allauth对接Google API(Gmail API)实现独立OAuth2授权

嘿,我正好折腾过这个需求,完全明白你想要独立于Google登录之外,单独获取Gmail API授权的诉求,下面一步步给你拆解怎么做:

1. 先搞定Google云平台的基础配置

首先你得去Google云控制台做些准备工作:

  • 创建一个新项目,在API库中找到并启用Gmail API
  • 进入「API和服务」→「凭据」页面,创建OAuth 2.0客户端ID,应用类型选择「Web应用」
  • 填写授权回调URL(本地测试可以填http://localhost:8000/accounts/google/gmail/callback/,线上环境要换成你的正式域名)
  • 创建完成后,把生成的客户端ID和客户端密钥存好,后面配置Django会用到

2. 配置Django项目与django-allauth

首先安装依赖包:

pip install django-allauth

接下来修改settings.py,把allauth相关的应用添加到INSTALLED_APPS里:

INSTALLED_APPS = [
    # 保留你原有的Django应用
    'django.contrib.sites',
    'allauth',
    'allauth.account',
    'allauth.socialaccount',
    'allauth.socialaccount.providers.google',
]

# 必须设置SITE_ID
SITE_ID = 1

# 配置认证后端
AUTHENTICATION_BACKENDS = [
    'django.contrib.auth.backends.ModelBackend',
    'allauth.account.auth_backends.AuthenticationBackend',
]

# 重点配置Google OAuth2参数,指定Gmail所需权限
SOCIALACCOUNT_PROVIDERS = {
    'google': {
        'SCOPE': [
            'https://www.googleapis.com/auth/gmail.readonly',  # 可根据需求调整权限,比如改成发送权限
            'openid',
        ],
        'AUTH_PARAMS': {
            'access_type': 'offline',  # 必须加这个才能获取刷新令牌,避免token过期后失效
            'prompt': 'consent',  # 每次授权都弹出同意页,确保能拿到刷新令牌
        }
    }
}

3. 自定义凭证存储模型

因为要和用户登录的社交账号分开存储,我们自己创建一个模型来保存Gmail的授权凭证:

# models.py
from django.db import models
from django.contrib.auth.models import User

class GmailCredential(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    access_token = models.CharField(max_length=500)
    refresh_token = models.CharField(max_length=500)
    expires_at = models.DateTimeField()

    def __str__(self):
        return f"{self.user.username}'s Gmail Credentials"

写完模型后别忘了执行数据库迁移:

python manage.py makemigrations
python manage.py migrate

4. 写触发授权的视图

这个视图用来生成Google的授权URL,然后重定向到授权页面:

# views.py
from django.shortcuts import redirect
from allauth.socialaccount.providers.google.provider import GoogleProvider
from allauth.socialaccount.models import SocialApp

def gmail_auth_init(request):
    # 获取我们在后台配置的Google应用
    social_app = SocialApp.objects.get(provider='google')
    provider = GoogleProvider(request)
    # 构建授权请求,指定自定义的回调URL
    auth_request = provider.get_auth_request(
        request,
        redirect_uri='http://localhost:8000/accounts/google/gmail/callback/'  # 要和Google控制台填的一致
    )
    return redirect(auth_request.url)

然后在urls.py里添加对应的路由:

# urls.py
from django.urls import path
from . import views

urlpatterns = [
    # 其他已有的路由
    path('accounts/google/gmail/auth/', views.gmail_auth_init, name='gmail_auth_init'),
    path('accounts/google/gmail/callback/', views.gmail_auth_callback, name='gmail_auth_callback'),
]

5. 自定义回调视图处理并存储凭证

这个视图是核心,用来处理Google授权后的回调,把拿到的token存到我们自己的模型里:

# views.py 继续添加
from django.contrib.auth.decorators import login_required
from allauth.socialaccount.models import SocialToken
from .models import GmailCredential
from datetime import datetime, timezone

@login_required
def gmail_auth_callback(request):
    # 用allauth的工具处理回调,拿到授权token
    provider = GoogleProvider(request)
    sociallogin = provider.sociallogin_from_request(request)
    token = sociallogin.token
    # 把token信息存到我们的自定义模型里
    credential, created = GmailCredential.objects.get_or_create(user=request.user)
    credential.access_token = token.token
    credential.refresh_token = token.token_secret
    # 把时间戳转成datetime格式存储
    credential.expires_at = datetime.fromtimestamp(token.expires_at, timezone.utc)
    credential.save()
    # 授权成功后重定向到你指定的页面,比如用户的Gmail管理页面
    return redirect('gmail_auth_success')

这里用了@login_required是因为要把凭证关联到当前登录的用户,但注意:这个授权是独立于Google登录的,用户可以用普通的用户名密码登录,再完成Gmail授权。

6. 在视图里调用Gmail API

现在有了存储的凭证,就可以在视图里调用Gmail API了,比如获取用户的邮件列表:

# views.py 继续添加
import requests
from django.shortcuts import render

@login_required
def gmail_get_emails(request):
    credential = GmailCredential.objects.get(user=request.user)
    # 先检查access_token是否过期
    if datetime.now(timezone.utc) >= credential.expires_at:
        # 用refresh_token刷新token
        social_app = SocialApp.objects.get(provider='google')
        provider = GoogleProvider(request)
        new_token = provider.refresh_token(
            social_app,
            credential.refresh_token
        )
        # 更新本地存储的凭证
        credential.access_token = new_token.token
        credential.expires_at = datetime.fromtimestamp(new_token.expires_at, timezone.utc)
        credential.save()
    # 调用Gmail API获取邮件列表
    headers = {'Authorization': f'Bearer {credential.access_token}'}
    response = requests.get(
        'https://www.googleapis.com/gmail/v1/users/me/messages',
        headers=headers,
        params={'maxResults': 10}
    )
    emails = response.json()
    # 把邮件数据传到模板展示
    return render(request, 'gmail_emails.html', {'emails': emails})

最后你可以写一个模板gmail_emails.html来展示这些邮件数据。

备注:内容来源于stack exchange,提问作者Kovy Jacob

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 09:05:30