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?
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 <form action="http://localhost:3000/google/sign-in" method="POST">
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.