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

如何在NextAuth v4会话期间为Google Provider新增Scope调用Google Fit API?

为已登录用户扩展NextAuth Google Provider的Google Fit API权限范围

1. 配置Google Fit所需的权限范围(Scope)

首先在Google Provider的授权配置中添加Google Fit API对应的Scope,可选择以下两种方式之一:

方式一:在自定义授权URL中追加Scope

修改你的GOOGLE_AUTHORIZATION_URL定义,加入Scope参数(根据业务需求选择具体权限):

const GOOGLE_AUTHORIZATION_URL =
    'https://accounts.google.com/o/oauth2/v2/auth?' +
    new URLSearchParams({
        prompt: 'consent',
        access_type: 'offline',
        response_type: 'code',
        // 组合基础权限与Google Fit权限
        scope: [
            'openid',
            'email',
            'profile',
            'https://www.googleapis.com/auth/fitness.activity.read',
            'https://www.googleapis.com/auth/fitness.body.read'
        ].join(' ')
    })

方式二:使用GoogleProvider自带的scope属性

若不想自定义完整授权URL,可直接在Provider配置中指定scope:

GoogleProvider({
    clientId: process.env.GOOGLE_CLIENT_ID,
    clientSecret: process.env.GOOGLE_CLIENT_SECRET,
    authorization: {
        url: 'https://accounts.google.com/o/oauth2/v2/auth',
        params: {
            prompt: 'consent',
            access_type: 'offline',
            response_type: 'code'
        }
    },
    // 直接声明所需权限范围
    scope: 'openid email profile https://www.googleapis.com/auth/fitness.activity.read https://www.googleapis.com/auth/fitness.body.read'
}),

2. 引导已登录用户重新授权

已登录用户此前未授权新增的Google Fit权限,需触发重新登录流程以获取包含新Scope的令牌。在前端添加授权按钮:

import { signIn, useSession } from 'next-auth/react'

function FitAuthButton() {
    const { data: session } = useSession()

    if (!session) return null

    return (
        <button
            onClick={() => {
                signIn('google', {
                    callbackUrl: '/',
                    authorizationParams: {
                        prompt: 'consent', // 强制弹出权限确认窗口
                    }
                })
            }}
        >
            授权Google Fit数据访问
        </button>
    )
}

export default FitAuthButton

用户点击按钮后会跳转至Google授权页,确认新增权限后,新生成的Access Token将包含Google Fit的访问权限。

3. 修复Refresh Token逻辑的潜在问题

当前refreshAccessToken函数中使用了refreshedTokens.expires_at,但Google OAuth端点返回的是expires_in(有效期秒数),需修正过期时间计算逻辑:

async function refreshAccessToken(token) {
    try {
        const url =
            "https://oauth2.googleapis.com/token?" +
            new URLSearchParams({
                client_id: process.env.GOOGLE_CLIENT_ID,
                client_secret: process.env.GOOGLE_CLIENT_SECRET,
                grant_type: "refresh_token",
                refresh_token: token.refreshToken,
            })

        const response = await fetch(url, {
            headers: {
                "Content-Type": "application/x-www-form-urlencoded",
            },
            method: "POST",
        })

        const refreshedTokens = await response.json()

        if (!response.ok) {
            throw refreshedTokens
        }

        return {
            ...token,
            accessToken: refreshedTokens.access_token,
            // 修复:用expires_in计算过期时间戳
            accessTokenExpires: Date.now() + refreshedTokens.expires_in * 1000,
            refreshToken: refreshedTokens.refresh_token ?? token.refreshToken,
        }
    } catch (error) {
        console.log(error)

        return {
            ...token,
            error: "RefreshAccessTokenError",
        }
    }
}

验证权限有效性

授权完成后,可通过调用Google Fit API验证权限:

async function fetchFitActivityData(accessToken) {
    const response = await fetch('https://www.googleapis.com/fitness/v1/users/me/dataset:aggregate', {
        method: 'POST',
        headers: {
            'Authorization': `Bearer ${accessToken}`,
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            aggregateBy: [{ dataTypeName: 'com.google.activity.segment' }],
            bucketByTime: { durationMillis: 86400000 },
            startTimeMillis: Date.now() - 7 * 86400000,
            endTimeMillis: Date.now()
        })
    })
    const data = await response.json()
    console.log('Fit活动数据:', data)
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 23:40:23