go 44 lines · 6 steps

Setting and reading secure session cookies in Go

Three helpers write, clear, and read a hardened session cookie using Go's net/http package.

Explained by highlit
1package auth
2 
3import (
4 "net/http"
5 "time"
6)
7 
8const sessionCookieName = "session_id"
9 
10func SetSessionCookie(w http.ResponseWriter, token string, ttl time.Duration) {
11 cookie := &http.Cookie{
12 Name: sessionCookieName,
13 Value: token,
14 Path: "/",
15 Expires: time.Now().Add(ttl),
16 MaxAge: int(ttl.Seconds()),
17 HttpOnly: true,
18 Secure: true,
19 SameSite: http.SameSiteStrictMode,
20 }
21 http.SetCookie(w, cookie)
22}
23 
24func ClearSessionCookie(w http.ResponseWriter) {
25 cookie := &http.Cookie{
26 Name: sessionCookieName,
27 Value: "",
28 Path: "/",
29 Expires: time.Unix(0, 0),
30 MaxAge: -1,
31 HttpOnly: true,
32 Secure: true,
33 SameSite: http.SameSiteStrictMode,
34 }
35 http.SetCookie(w, cookie)
36}
37 
38func SessionToken(r *http.Request) (string, error) {
39 cookie, err := r.Cookie(sessionCookieName)
40 if err != nil {
41 return "", err
42 }
43 return cookie.Value, nil
44}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Centralizing the cookie name in one constant keeps writing, clearing, and reading perfectly in sync.
  2. 2HttpOnly, Secure, and SameSite=Strict are the baseline flags that harden a session cookie against theft and CSRF.
  3. 3Clearing a cookie means re-sending it with an expired date and a negative MaxAge, not just dropping it.

Related explainers

typescript
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { ConfigService } from '@nestjs/config';

How a JWT strategy authenticates in NestJS

authentication jwt passport
Intermediate 7 steps
go
package theme
 
import (
	"fmt"

Per-tenant HTML templates with Gin's renderer

multi-tenancy concurrency html-templates
Advanced 8 steps
typescript
import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpErrorResponse } from '@angular/common/http';
import { BehaviorSubject, Observable, throwError } from 'rxjs';
import { catchError, filter, take, switchMap } from 'rxjs/operators';

Refreshing auth tokens in an Angular interceptor

http-interceptor token-refresh rxjs
Advanced 8 steps
typescript
import { CanActivate, ExecutionContext, Injectable, UnauthorizedException } from '@nestjs/common';
import { GqlExecutionContext } from '@nestjs/graphql';
import { Reflector } from '@nestjs/core';
import { JwtService } from '@nestjs/jwt';

How a GraphQL auth guard works in NestJS

authentication authorization jwt
Intermediate 7 steps
go
package middleware
 
import (
	"net/http"

A maintenance-mode gate in Gin

middleware atomic-flag concurrency
Intermediate 8 steps
go
func ServeVideo(c *gin.Context) {
	id := c.Param("id")
	video, err := videoRepo.FindByID(c.Request.Context(), id)
	if err != nil {

Streaming video files with Gin

http streaming range requests file serving
Intermediate 6 steps

Share this explainer

Here's the card — post it anywhere.

Setting and reading secure session cookies in Go — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code