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
‹ swipe to step through ›
Walkthrough
Space play
←→ step
click any line
Three takeaways
- 1Centralizing the cookie name in one constant keeps writing, clearing, and reading perfectly in sync.
- 2HttpOnly, Secure, and SameSite=Strict are the baseline flags that harden a session cookie against theft and CSRF.
- 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.
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code
Embed this explainer
Drop the interactive walkthrough into a blog or docs. Views never cost a credit.
<iframe src="https://highlit.co/explainers/setting-and-reading-secure-session-cookies-in-go-explained-go-760d/embed?autoplay=1" width="100%" height="520" loading="lazy" style="border:0"></iframe>
Autoplay is on by default — add ?autoplay=0 to start paused.