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

使用Django allauth谷歌登录成功但无法获取Access Token的问题

Django allauth谷歌登录获取Access Token问题解决

我正在使用Django allauth实现谷歌身份认证功能,目前已成功完成谷歌登录,但无法获取Access Token,数据库中也未存储该Token。请问如何从谷歌登录中获取Access Token?

现有配置文件展示

settings.py

from pathlib import Path
import os
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent


# Quick-start development settings - unsuitable for production

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-9#c!e&s(-o9-6u^mt#w(w6s$ober^f(m45)=f)=m&zo1$dlcg&'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []


# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'allauth', # Social login App
    'allauth.account', # login App
    'allauth.socialaccount', # Social login App
    'allauth.socialaccount.providers.google', # Google login App
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    "API", # API APP
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    "allauth.account.middleware.AccountMiddleware"
]

ROOT_URLCONF = 'MassMail.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            os.path.normpath(os.path.join(BASE_DIR, 'templates')),
        ],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
                'django.template.context_processors.request', # requirements for django-all-auth
            ],
        },
    },
]

WSGI_APPLICATION = 'MassMail.wsgi.application'


# Database

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}


# Password validation

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


# Google Authentication
SITE_ID = 1

AUTHENTICATION_BACKENDS = [
    'django.contrib.auth.backends.ModelBackend',
    'allauth.account.auth_backends.AuthenticationBackend',
]

LOGIN_REDIRECT_URL = '/accounts/profile/'

# Provider specific settings
SOCIALACCOUNT_PROVIDERS = {
    'google': {
        'FETCH_USERINFO' : True,
        'SCOPE': [
            'profile',
            'email',
            'https://www.googleapis.com/auth/gmail.modify',
            'https://www.googleapis.com/auth/gmail.send',
        ],
        'AUTH_PARAMS': {
            'access_type': 'online',
        },
        'OAUTH_PKCE_ENABLED': True,
    }
}



# Internationalization

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)

STATIC_URL = 'static/'

# Default primary key field type

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

项目urls.py

from django.contrib import admin
from django.urls import path,include

urlpatterns = [
    path('admin/', admin.site.urls),
    path("accounts/", include("API.urls")),
]

API urls.py

from django.urls import path,include
from . import views


urlpatterns = [
    path("profile/",views.ProfileView.as_view(),name='user_profile'),
    path('', include("allauth.urls")),
]

解决步骤

1. 修改谷歌Provider的授权类型

在settings.py的SOCIALACCOUNT_PROVIDERS配置中,将谷歌的access_type从online改为offline:

'SOCIALACCOUNT_PROVIDERS': {
    'google': {
        # ... 其他配置
        'AUTH_PARAMS': {
            'access_type': 'offline',  # 修改这里
        },
        # ... 其他配置
    }
}

online模式仅返回短期有效且不持久化存储的Access Token,而offline模式会请求离线访问权限,不仅会返回Access Token,还会生成Refresh Token,并且allauth会自动将这两个Token存储到数据库中。

2. 确保Token存储功能开启

在settings.py中显式添加以下配置,确认allauth开启Token存储:

SOCIALACCOUNT_STORE_TOKENS = True

这是allauth的默认配置,但显式声明可以避免因环境差异导致的问题。

3. 重新授权登录

修改配置后,需要让用户退出当前登录并重新通过谷歌授权登录——因为之前的授权请求没有包含offline权限,旧的授权记录不会生成可存储的Token。

4. 在视图中获取Access Token

登录完成后,你可以在视图中通过用户关联的SocialAccount和SocialToken模型获取Token。以你的ProfileView为例:

from django.views import View
from django.http import HttpResponse
from allauth.socialaccount.models import SocialAccount, SocialToken
from allauth.socialaccount.providers.google.provider import GoogleProvider

class ProfileView(View):
    def get(self, request):
        if not request.user.is_authenticated:
            return HttpResponse("请先登录")
        
        # 获取用户关联的谷歌社交账户
        google_account = SocialAccount.objects.filter(
            user=request.user, 
            provider=GoogleProvider.id
        ).first()
        
        if not google_account:
            return HttpResponse("未关联谷歌账户")
        
        # 获取对应的Token记录
        social_token = SocialToken.objects.filter(account=google_account).first()
        
        if social_token:
            access_token = social_token.token
            refresh_token = social_token.token_secret
            # 这里可以将Token用于后续业务逻辑,比如调用Gmail API
            return HttpResponse(f"Access Token: {access_token}<br>Refresh Token: {refresh_token}")
        
        return HttpResponse("未获取到Token,请重新授权登录")

5. 验证数据库存储

重新登录后,你可以检查数据库中的socialaccount_socialtoken表,里面应该会生成一条关联该用户谷歌账户的记录,包含token(Access Token)和token_secret(Refresh Token)字段。

内容的提问来源于stack exchange,提问作者Akrash Nadeem

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 01:03:12