
google oauth 访问令牌(access token)有效期仅1小时,不应长期存储;应安全保存的是长期有效的刷新令牌(refresh token),用于按需获取新访问令牌,数据库存储是标准做法,加密非强制但推荐。
在集成 Google Calendar API 时,正确管理 OAuth 凭据是保障功能可用性与安全性的关键。许多开发者误将短期有效的 access_token 视为持久化目标,实则应聚焦于长期有效的 refresh_token —— 它由 Google 在首次授权成功后一次性发放(前提是在 access_type=offline 模式下请求),可在用户未主动撤回授权的前提下长期有效(除非被显式撤销或因策略变更失效)。
✅ 推荐存储方案:数据库 + refresh_token 为核心
每个用户对应一条记录,建议在用户表(如 users)中添加以下字段:
ALTER TABLE users ADD COLUMN google_refresh_token TEXT, ADD COLUMN google_access_token TEXT, -- 可选:仅作临时缓存,非必需 ADD COLUMN google_token_expires_at DATETIME; -- 记录 access_token 过期时间(ISO 8601 时间戳)
⚠️ 注意:access_token 无需持久化入库。它仅用于即时 API 调用,应在内存中使用、过期后立即丢弃,并通过 refresh_token 动态刷新。
? 使用 refresh_token 获取新 access_token(PHP 示例)
使用 Google API Client Library for PHP 时,可直接构造 Google_Service_Oauth2 或复用 Google_Client 的凭据加载逻辑。关键在于替换默认的文件读取行为:
// 假设已从数据库查得用户 $user['google_refresh_token']
$client = new Google_Client();
$client->setApplicationName('My Calendar App');
$client->setScopes(Google_Service_Calendar::CALENDAR);
$client->setAuthConfig('credentials.json');
$client->setAccessType('offline');
// 手动设置刷新令牌(跳过文件读取)
$token = [
'refresh_token' => $user['google_refresh_token'],
'expires_in' => 3600,
'created' => time(),
];
$client->setAccessToken($token);
// 若 access_token 已过期,库会自动用 refresh_token 请求新 token
if ($client->isAccessTokenExpired()) {
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
$newToken = $client->getAccessToken();
// 【可选】更新数据库中的 access_token 和过期时间(便于调试或前端展示)
$pdo->prepare(
"UPDATE users SET google_access_token = ?, google_token_expires_at = ? WHERE id = ?"
)->execute([
json_encode($newToken),
date('Y-m-d H:i:s', $newToken['created'] + $newToken['expires_in']),
$user['id']
]);
}? 安全注意事项
- refresh_token 是敏感凭证:虽不能单独用于调用 API,但配合你的 client_id 和 client_secret 即可无限换取 access_token。因此:
- client_secret 必须保密:切勿硬编码在前端或公开仓库中,应通过环境变量注入;
- 定期轮换与监控:为高权限账号启用 Google Cloud 的 OAuth 应用审核日志,及时发现异常刷新行为。
? 总结
| 项目 | 是否存储 | 是否加密 | 说明 |
|---|---|---|---|
| access_token | ❌ 否(仅内存缓存) | — | 1 小时过期,每次调用前校验并刷新 |
| refresh_token | ✅ 是(每用户唯一) | ✅ 强烈推荐 | 唯一长期凭证,丢失即失去用户日历访问权 |
| client_id/client_secret | ✅ 是(应用级配置) | ✅ 必须 | 属于应用密钥,需环境隔离与加密管理 |
遵循此模式,你既能保障多用户场景下的 OAuth 流程健壮性,又能满足基本安全合规要求。










