Golang Set-Cookie with Fetch API

This article summarizes how to set browser cookies. The frontend uses the Fetch API, and the backend uses Golang.

Backend Configuration

The Golang code is as follows:

func handler(w http.ResponseWriter, r *http.Request) {
    // Do something
    cookie := &http.Cookie{
        Name:     "key",
        Value:    "value",
        Path:     "/",
        HttpOnly: true,
        // Secure:   true,
    }

    http.SetCookie(w, cookie)
    // Do something or return
}

Note that in production, you must enable Secure to force HTTPS usage. If not using HTTPS, the cookie will not be set by the browser and will not be sent back to the server, but the cookie will still be sent to the browser.

If Nginx manages CORS, the backend no longer needs to handle it, otherwise there may be conflicts.

Frontend Configuration

For the frontend JavaScript code, if using the Fetch API, you need to enable credentials: 'include' because Fetch does not send or accept cookies by default. Here, it’s about accepting cookies, not receiving them, as cookies can be returned to the client but not set.

fetch('http://localhost:4000/user/login', {
    headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
    },
    method: 'POST',
    body: JSON.stringify(data),
    mode: 'cors',
    cache: 'no-cache',
    redirect: 'follow',
    credentials: 'include'
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));

Important Points

  • Cookie Attributes:

    • Name and Value: The cookie’s key and value.
    • Path: The path where the cookie is valid (e.g., “/” for the entire site).
    • HttpOnly: Prevents access via JavaScript for security.
    • Secure: Ensures the cookie is only sent over HTTPS.
    • MaxAge or Expires: Sets the cookie’s lifetime.
  • CORS Considerations: When dealing with cross-origin requests, ensure the server sets appropriate CORS headers. For cookies, the server must include Access-Control-Allow-Credentials: true and specify allowed origins.

  • Security Best Practices:

    • Always use Secure in production.
    • Set HttpOnly to prevent XSS attacks.
    • Use SameSite attribute to control cross-site requests (e.g., SameSite: 'Strict' or 'Lax').
  • Troubleshooting:

    • If cookies aren’t being set, check browser developer tools for network requests and console errors.
    • Ensure the domain and path match the request.
    • For local development, you may need to disable Secure or use HTTP.

Resources