6

I am creating a React app with a Go server. I set the cookie on the login request's response with http.cookie, which sends it back as seen in the network tab. But the browser doesn't save it. Tried with Chrome and Firefox. What am I doing wrong?

// Cors handler
r.Use(cors.Handler(cors.Options{
    AllowOriginFunc:  AllowOriginFunc,
    AllowedMethods:   []string{"GET", "POST", "DELETE"},
    AllowedHeaders:   []string{"*"},
    AllowCredentials: true,
}))
func AllowOriginFunc(r *http.Request, origin string) bool {
    if origin == "http://localhost:3000" || origin == "http://127.0.0.1:3000" {
        return true
    }
    return false
}

// End of Login route sending back the token
    userDetails := types.User{Name: user.Name, Email: user.Email, Profile_Pic: user.Profile_Pic}
    cookie := &http.Cookie{Name: "accessToken", Value: token, MaxAge: int(maxAge), Path: "/api", HttpOnly: true, SameSite: http.SameSiteLaxMode}
    http.SetCookie(w, cookie)
    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(userDetails)

Edit: Screenshots of the network tab. Response headers

Request headers

Daniel Chettiar
  • 311
  • 2
  • 9

2 Answers2

12

Anybody else who comes across a similar problem, and is using the Fetch API, try setting 'credentials: "include"' in your fetch request that is EXPECTING A COOKIE IN THE RESPONSE. The browser then set the cookie it got in the response.

I had the wrong assumption that the 'credentials' flag must be set for requests that occur after the cookie is received. Finally working. Can't believe I spent 12 hours on setting a cookie smh.

fetch(`${url}/login`, {
                method: "POST",
                headers: {
                    "Content-Type": "application/json",
                },
                credentials: "include", // This here
                body: JSON.stringify({
                    email: userDetails.email,
                    password: userDetails.password,
                }),
            }).then((response) => { ...
Daniel Chettiar
  • 311
  • 2
  • 9
  • Your Go server works with CORS scenario `// Cors handler r.Use(cors.Handler(cors.Options{ AllowOriginFunc: AllowOriginFunc, AllowedMethods: []string{"GET", "POST", "DELETE"}, AllowedHeaders: []string{"*"}, AllowCredentials: true, }))` [Here](https://developer.mozilla.org/en-US/docs/Web/API/Request/credentials) it is explicitly stated that `credentials="include"` means _Always send user credentials (cookies, basic http auth, etc..), even for cross-origin calls._ – vtm11 Jun 14 '22 at 10:26
  • Thank you so much for this! I just ran into this and have been going nuts trying to work it out. A thousand thank yous! – JK Gunnink Oct 15 '22 at 04:37
0

please try to put you cookie in header filed:"Set-Cookie".

e.g:

w.Header().Set("Set-Cookie","cookieName=cookieValue")

Make sure the response header has this field, and check it in you browser devtools.

milkdove
  • 56
  • 1
  • Tried your suggestion, didn't work :-( http.Cookie actually does set the cookie in the response header, it's seen in the network tab. I donno why the browsers aren't saving it. Also tried setting Allow All Cookies in Chrome settings, nada. – Daniel Chettiar Jun 14 '22 at 07:32
  • Maybe the problem is that the properties of the cookie are set incorrectly,not the browser is not saving. If the request URL by the front-end is different from the domain and path of the cookie, this request will not bring the corresponding cookie. You can view all properties of the cookie in devtools-application-cookies in the browser – milkdove Jun 14 '22 at 07:52
  • The domains for the frontend and backend are localhost, and it's cross-origin, . I've added screenshots to the post, maybe that's helpful. – Daniel Chettiar Jun 14 '22 at 08:04
  • Please try IP instead of localhost,like 127.0.0.1.Including front end request address and browser access address – milkdove Jun 15 '22 at 02:06