在重定向后使用Gin的Golang中出现CORS错误。

huangapple go评论92阅读模式
英文:

CORS Error in Golang with Gin after Redirect

问题

我正在尝试在使用Gin编写的Go Web服务器中实现Google OAuth2。我已经添加了两个新的端点,分别是/google/sign-in和/google/callback。第一个端点接收请求并重定向到Google授权URL,第二个端点在用户选择有效的Google帐户后被调用,验证令牌并为我的内部身份验证创建一个JWT。

一切都很好,除了一个问题,就是当我调用第一个API路由时,我收到了一个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.

这是我的Go代码:

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 Controller

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中,回调URL是http://localhost:3000/google/callback,并且已添加到Google Cloud OAuth凭据中。

我理解我在回调请求中缺少了Access-Control-Allow-Origin头,但是我该如何添加这个头呢?

英文:

I'm trying to implement google oauth2 in my web server written in Go with gin. I've added two new endpoints called /google/sign-in and /google/callback. The first received the request and redirect to google auth url, and the second is called after the user selected a valid google account, verify the token and create a jwt for my internal authentication.

All is good, except it's not, because when I'm calling the first API route I get a CORS error:

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.

This is my golang code:

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 Controller

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)
}

In googleAuthConfig there is the callback url that is http://localhost:3000/google/callback and it's added to the google cloud oauth credentials.

I undertand that I miss the Access-Control-Allow-Origin in the callback request, but how can I add that header?

答案1

得分: 1

根据问题中的信息,您正在访问位于http://localhost:4200的页面,并发送一个AJAX请求到http://localhost:3000/google/sign-in,该请求被重定向到https://accounts.google.com/o/oauth2/auth。这样是行不通的。您需要将页面重定向到https://accounts.google.com/o/oauth2/auth

修复此问题有两个选择:

  • 修改客户端代码,将AJAX请求替换为表单请求(使用<form action="http://localhost:3000/google/sign-in" method="POST">元素)。在这种情况下,RedirectToGoogleAuthPage中的c.JSON应该被替换为其他内容。

  • 或者修改RedirectToGoogleAuthPage以响应包含要重定向到的目标URL的JSON内容,并修改客户端代码以将页面重定向到目标URL(使用window.location = targetURL)。

看起来第二个选择对您的代码需要的更改较少。

英文:

According to the information in the question, you are accessing the page at http://localhost:4200, and sending an AJAX request to http://localhost:3000/google/sign-in, which redirects the request to https://accounts.google.com/o/oauth2/auth. This won't work. You need a page redirect to https://accounts.google.com/o/oauth2/auth instead.

There are two choices to fix the issue:

  • Modify the client code to replace the AJAX request with a form request (using a &lt;form action=&quot;http://localhost:3000/google/sign-in&quot; method=&quot;POST&quot;&gt; element). In this case, c.JSON in RedirectToGoogleAuthPage should be replaced with something else.

  • Or modify RedirectToGoogleAuthPage to response with a JSON content that contains the target URL to redirect to, and modify the client code to redirect the page to the target URL (with window.location = targetURL).

Looks like the second choice requires less change to your code.

huangapple
  • 本文由 发表于 2023年7月22日 21:24:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/76744012.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定