How to Set and Get Cookies in Golang Server

Robin
Updated on December 1, 2023

You can set any number of cookies to the response in your Go Server using the net/http package. It has built-in methods like Cookies() and SetCookies() for that.

It is also easy to retrieve cookies from an incoming request by calling Cookies() method from http.Request inside that route handler.

Set Cookies in a Golang Server

Before setting a cookie, you have to create one. You can create a cookie using the http.Cookie struct.

You can initialize this struct with all the cookie attributes and then you can set the returned value as a cookie inside your route handler.

This is the http.Cookie struct:

          type Cookie struct {
	Name  string
	Value string

	Path       string    // optional
	Domain     string    // optional
	Expires    time.Time // optional
	RawExpires string    // for reading cookies only

	// MaxAge=0 means no 'Max-Age' attribute specified.
	// MaxAge<0 means delete cookie now, equivalently 'Max-Age: 0'
	// MaxAge>0 means Max-Age attribute present and given in seconds
	MaxAge   int
	Secure   bool
	HttpOnly bool
	SameSite SameSite
	Raw      string
	Unparsed []string // Raw text of unparsed attribute-value pairs
}

        

Here's an explanation of each field:

  • Name: The name of the cookie. It is a string that identifies the cookie.
  • Value: The value associated with the cookie. It is also a string and represents the information stored in the cookie.
  • Path: The URL path for which the cookie is valid. If not set, the cookie is valid for all paths.
  • Domain: The domain for which the cookie is valid. If not set, the cookie is valid for the domain of the request.
  • Expires: The expiration time for the cookie. After this time, the cookie is considered expired, and the browser will remove it.
  • RawExpires: This field is used for reading cookies only. It contains the raw text representation of the expiration time.
  • MaxAge: Specifies the maximum age of the cookie in seconds. A value of 0 means no 'Max-Age' attribute is specified. A value less than 0 means the cookie should be deleted immediately. A value greater than 0 means the 'Max-Age' attribute is present and given in seconds.
  • Secure: If true, the cookie should only be sent over secure (HTTPS) connections.
  • HttpOnly: If true, the cookie is marked as HttpOnly, meaning it is not accessible via client-side JavaScript. This is a security measure against certain types of attacks, such as cross-site scripting (XSS).
  • SameSite: An enum representing the SameSite attribute of the cookie. It can take values from the http.SameSite type, which includes http.SameSiteDefaultMode, http.SameSiteLaxMode, http.SameSiteNoneMode and http.SameSiteStrictMode. This attribute helps mitigate cross-site request forgery (CSRF) attacks.
  • Raw: The raw text of the cookie, including all attributes and values as received from the client or to be sent to the client.
  • Unparsed: A slice of strings representing the raw text of unparsed attribute-value pairs. This is useful for handling custom or unknown cookie attributes.

You can learn more about these attributes by clicking here.

While creating a new cookie "Name" and "Value" attributes are required.

Here Name is the name of your cookie. You will use this name to get the cookie from a request in the next section.

And the Value is the data you want to store inside your cookie. It will be stored as a string.

          package main

import (
	"fmt"
	"net/http"
	"time"
)

func loginHander(w http.ResponseWriter, r *http.Request) {
	// Create a new cookie
	cookie := http.Cookie{
		Name:    "token",
		Value:   "0rPKW5dUd914eS4qBYzkPBXlVHCzgPl1JHxYZJrQZUfo9uwWKtMiDtFQQ7rWoEuP",
		Expires: time.Now().Add(24 * time.Hour), // Cookie expires in 24 hours
		HttpOnly: true,
		Path: "/",
		Secure: false,
		SameSite: http.SameSiteStrictMode,
	}
	
	// Set the cookie in the response
	http.SetCookie(w, &cookie)

	fmt.Fprintln(w, "You are now logged in")	
}

func main() {
	http.HandleFunc("/login", loginHander)

	// http.HandleFunc("/dashboard", dashboardHander)

	// Start the server on port 8000
	err := http.ListenAndServe(":8000", nil)
	if err != nil {
		fmt.Println("Error starting server:", err)
	}
}

        

I have a "/login" route. If someone visits this route, it will execute the loginHander() function.

Inside this function, I am creating a cookie called token with a value using http.Cookie struct.

You can set other attributes for your cookie according to your requirements.

Next, I am calling http.SetCookie() method to set my newly created cookie to the response.

This method takes 2 parameters: an instance of http.ResponseWriter and a pointer to a http.Cookie type.

When you call this method with these parameters, it will attach a Set-Cookie header to the HTTP response which will inform the browser to store your cookie.

That's how easy it is to create cookies inside a Golang server using the net/http package.

Also Read: How to Set or Get HTTP Headers in Golang Server


Set Multiple Cookies in a Go Server

You can also set multiple cookies inside a single Golang route handler. You have to follow the same process shown in the previous section for each cookie.

You can use the http.SetCookie() method multiple times, each time with a different http.Cookie.

          func loginHander(w http.ResponseWriter, r *http.Request) {
	// Create a token cookie
	tokenCookie := http.Cookie{
		Name:    "token",
		Value:   "0rPKW5dUd914eS4qBYzkPBXlVHCzgPl1JHxYZJrQZUfo9uwWKtMiDtFQQ7rWoEuP",
		Expires: time.Now().Add(24 * time.Hour), // Cookie expires in 24 hours
		HttpOnly: true,
		Path: "/",
		Secure: false,
		SameSite: http.SameSiteStrictMode,
	}
	
	// Set the "token" cookie in the response
	http.SetCookie(w, &tokenCookie)

	// Create a website cookie
	websiteCookie := http.Cookie{
		Name:    "website",
		Value:   "Web Mound",
		Expires: time.Now().Add(24 * time.Hour), // Cookie expires in 24 hours
		HttpOnly: true,
		Path: "/",
		Secure: false,
		SameSite: http.SameSiteStrictMode,
	}
	
	// Set the "website" cookie in the response
	http.SetCookie(w, &websiteCookie)

	fmt.Fprintln(w, "You are now logged in")	
}

        

Here I am creating tokenCookie and websiteCookie with the names token and website respectively using the http.Cookie struct.

You have to set those cookies separately by calling the http.SetCookie() method 2 times.


Get Cookies in a Golang Server

To retrieve a cookie from an incoming HTTP request, you can use the Cookies() method from the *http.Request parameter.

This method takes 1 parameter which is the name of the cookie you want to get.

It will return the cookie from the request or an error if there is no cookie with that name.

If there are multiple cookies with the given name, it will only return one cookie.

          package main

import (
	"fmt"
	"net/http"
	"time"
)

// ...

func dashboardHander(w http.ResponseWriter, r *http.Request) {
	// Retrieve the tokenCookie by name
	tokenCookie, err := r.Cookie("token")
	
	if err != nil {
		// Handle error here
		fmt.Fprintln(w, "No token found")	
		return
	}
	
	fmt.Println(tokenCookie.Value)

	fmt.Fprintln(w, "Dashboard Page")	
}

func main() {
	http.HandleFunc("/login", loginHander)

	http.HandleFunc("/dashboard", dashboardHander)

	// Start the server on port 8000
	err := http.ListenAndServe(":8000", nil)
	if err != nil {
		fmt.Println("Error starting server:", err)
	}
}

        

Here inside my dashboardHander() function, I am calling r.Cookie() method with the name token to get this cookie.

If there is an error you can check and handle it using the if statement. Otherwise, the tokenCookie variable will have the token cookie.

You can get the cookie value from the tokenCookie.Value property. You can also access other cookie attributes like Name, Expires, HttpOnly, MaxAge, Path, Secure, etc.

Also Read: What is HTTP HandlerFunc in Go? Complete Guide with Examples


Get All Cookies in a Go Server

To retrieve all cookies from an incoming HTTP request in a Golang server, you can use the r.Cookies() method.

This method returns a slice of cookies present in the request

          func dashboardHander(w http.ResponseWriter, r *http.Request) {
	// Retrieve all cookies from the request
	cookies := r.Cookies()

	// Loop through the cookies and print their names and values
	for _, cookie := range cookies {
		fmt.Printf("Cookie Name: %s, Value: %s\n", cookie.Name, cookie.Value)
	}

	fmt.Fprintln(w, "Dashboard Page")	
}

        

When you call the r.Cookies() method, it will return all the cookies as a slice of *http.Cookie from the request.

Now you can loop through those cookies and access their values as well as other properties.

Related Posts