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

添加Google授权Scope时触发oauth2: invalid_grant错误的求助

使用github.com/markbates/goth添加Google OAuth Scope时出现invalid_grant错误的排查与解决

问题背景

现有基于github.com/markbates/goth实现的Google用户授权代码,无额外Scope时运行正常,但添加任意Google官方Scope(如YouTube相关权限)后,调用CompleteUserAuth函数会触发oauth2: "invalid_grant" "Bad Request"错误——授权流程能正常引导用户完成Google登录,但无法获取有效访问令牌。相同逻辑的Twitch授权无此问题。

关联代码文件如下:

auth.go

package auth

import (
    "os"

    "github.com/gorilla/sessions"
    "github.com/joho/godotenv"
    "github.com/markbates/goth"
    "github.com/markbates/goth/gothic"
    "github.com/markbates/goth/providers/google"
)

const (
    MaxAge = 86400 * 30
    IsProd = false
)

func NewAuth() {
    godotenv.Load(".env")

    key := os.Getenv("RANDOM_KEY")
    googleClientID := os.Getenv("GOOGLE_CLIENT_ID")
    googleClientSecret := os.Getenv("GOOGLE_CLIENT_SECRET")

    store := sessions.NewCookieStore([]byte(key))
    store.MaxAge(MaxAge)

    store.Options.Path = "/"
    store.Options.HttpOnly = true
    store.Options.Secure = IsProd

    gothic.Store = store

    goth.UseProviders(
        google.New(
            googleClientID, googleClientSecret, "http://localhost:8080/auth/google",
            // "https://www.googleapis.com/auth/youtube.readonly",
            // "https://www.googleapis.com/auth/youtube.channel-memberships.creator",
            // "https://www.googleapis.com/auth/yt-analytics.readonly",
        )
    )
}

handler_login.go

package main

import (
    "context"
    "fmt"
    "net/http"

    "github.com/go-chi/chi/v5"
    "github.com/markbates/goth/gothic"
)

func (cfg *apiConfig) handlerAuthLogin(w http.ResponseWriter, r *http.Request) {
    provider := chi.URLParam(r, "provider")
    r = r.WithContext(context.WithValue(context.Background(), "provider", provider))
    if user, err := gothic.CompleteUserAuth(w, r); err == nil {
        http.Redirect(w, r, "http://localhost:5173", http.StatusFound)
        cfg.createUser(w, r, user)
        return
    } else {
        gothic.BeginAuthHandler(w, r)
    }
}

排查与解决建议

1. 核对Google Cloud Console的Scope配置

  • 确认添加的Scope已在OAuth同意屏幕中添加并发布:测试阶段需将测试用户邮箱加入“测试用户”列表,未发布的Scope仅对测试用户生效
  • 检查Scope拼写:比如YouTube相关Scope的路径是否完全正确,避免因拼写错误导致授权失败
  • 敏感Scope需审核:部分涉及用户隐私的Scope需要Google人工审核,未通过审核前无法正常使用,可在Cloud Console的“OAuth同意屏幕”查看审核状态

2. 验证Session存储的一致性

  • 检查gothic.Store的配置:添加Scope后,授权流程中的临时OAuth状态需要正确存入Session,确保CookieStore的HttpOnly、Secure等参数符合当前环境(本地测试Secure设为false没问题)
  • 清除旧Session数据:重启服务,或手动清除浏览器缓存中的Cookie,避免旧的授权状态干扰新流程
  • 临时降低Session有效期:将MaxAge调小,测试是否因Session过期导致令牌请求失败

3. 确认回调URL的一致性

  • 确保Google Cloud Console中配置的回调URL与代码中的"http://localhost:8080/auth/google"完全一致,包括协议(HTTP/HTTPS)、端口、路径
  • 部分敏感Scope要求回调URL必须为HTTPS:本地测试可使用ngrok等工具将本地服务转为HTTPS,验证是否解决问题

4. 排查goth库的Scope处理逻辑

  • 升级依赖:将goth和goth/providers/google升级到最新版本,可能存在的Scope传递bug已被修复
  • 检查Scope参数传递:查看goth的Google Provider源码,确认New方法的Scope参数是否被正确编码并附加到授权URL中
  • 手动调试授权请求:通过浏览器开发者工具查看授权跳转URL,确认Scope参数是否存在且正确

5. 排查令牌请求的关键参数

  • 打印详细错误信息:在CompleteUserAuth的错误分支中添加日志,输出完整错误信息,比如:
    } else {
        fmt.Printf("授权完成错误详情: %+v\n", err)
        gothic.BeginAuthHandler(w, r)
    }
    
  • 检查授权Code的有效性:invalid_grant常见原因包括Code已过期(默认10分钟)、重复使用,确保每次授权流程使用全新的Code
  • 验证令牌请求参数:确认向Google令牌端点发送的code、client_id、client_secret、redirect_uri参数完全正确,无拼写或格式错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 08:57:51