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

Gin框架Go实现Google OAuth2重定向时遭遇CORS错误求助

Gin框架Google OAuth2认证的CORS错误解决

问题场景

我使用Go语言的Gin框架搭建Web服务,实现Google OAuth2认证,新增了两个端点:

  • /google/sign-in:接收请求后重定向至谷歌授权页面
  • /google/callback:用户选择有效谷歌账号后验证令牌并生成内部JWT

调用/google/sign-in时触发CORS错误,具体信息如下:

Access to XMLHttpRequest at 'https://accounts.google.com/o/oauth2/auth?access_type=online&client_id=xxxxxxxxxxxxx-337ka657nqlo84q6697vv2efsc2vqvm0.apps.googleusercontent.com&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fgoogle%2Fcallback&response_type=code&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile&state=7e5f86fe352b4563c7d1bd62408285dcbc44e3e26a4f142bbae915279008ece6' (redirected from 'http://localhost:3000/google/sign-in') from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

我的代码

Gin路由配置

r := gin.Default()

r.Use(cors.New(cors.Config{
    AllowOrigins: []string{"*"},
    AllowMethods: []string{"GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"},
    AllowHeaders: []string{"Origin", "Authorization", "Content-Type", "Content-Length", "Accept-Encoding", "X-CSRF-Token", "baggage", "sentry-trace", "X-User-Lang"},
}))

r.POST("/google/sign-in", authController.RedirectToGoogleAuthPage)
r.GET("/google/callback", authController.GoogleSignIn)

Auth控制器代码

func (a AuthController) RedirectToGoogleAuthPage(c *gin.Context) {
  googleAuthConfig := utils.GetGoogleAuthConfig()
  state := utils.GenerateRandomKey()
  url := googleAuthConfig.AuthCodeURL(state, oauth2.AccessTypeOnline)
  session := sessions.Default(c)
  session.Set(state, state)
  err := session.Save()
  if err != nil {
      c.JSON(http.StatusInternalServerError, a.Errors.InternalError(err.Error()))
      return
  }
  c.Header("X-Auth-State", state)
  c.Redirect(http.StatusTemporaryRedirect, url)
}

注:googleAuthConfig已配置回调地址为http://localhost:3000/google/callback,且已添加至谷歌云OAuth凭据中。

解决方案

核心原因

你用AJAX请求POST接口触发重定向,但浏览器的AJAX请求受CORS规则限制,无法跨域跳转到第三方域名(谷歌账号页),且谷歌的响应不会携带Access-Control-Allow-Origin头,导致报错。

方案1:修改接口为GET,前端直接跳转

  1. 调整路由方法为GET:
// 把POST改成GET
r.GET("/google/sign-in", authController.RedirectToGoogleAuthPage)
  1. 前端不要用AJAX请求,而是通过页面跳转访问该接口:
  • 用HTML标签:<a href="http://localhost:3000/google/sign-in">谷歌登录</a>
  • 或JS代码:window.location.href = "http://localhost:3000/google/sign-in"

这种方式符合OAuth2的常规流程,浏览器页面跳转不受CORS限制。

方案2:后端返回授权URL,前端自行跳转

如果必须保留POST方法(比如需要传递额外参数),可以修改控制器代码,返回谷歌授权URL给前端,由前端主动跳转:

func (a AuthController) RedirectToGoogleAuthPage(c *gin.Context) {
  googleAuthConfig := utils.GetGoogleAuthConfig()
  state := utils.GenerateRandomKey()
  url := googleAuthConfig.AuthCodeURL(state, oauth2.AccessTypeOnline)
  session := sessions.Default(c)
  session.Set(state, state)
  err := session.Save()
  if err != nil {
      c.JSON(http.StatusInternalServerError, a.Errors.InternalError(err.Error()))
      return
  }
  // 返回授权URL和state,由前端跳转
  c.JSON(http.StatusOK, gin.H{
      "auth_url": url,
      "state": state,
  })
}

前端拿到auth_url后执行:window.location.href = auth_url,即可避开CORS问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 20:24:51