liveBook · Manning

JSON Web Token

As explained in Go in Practice, Second Edition

A JSON Web Token is a signed token format for transmitting claims between parties, commonly including identity information.

A JSON Web Token (JWT) is a signed JSON-based token that carries claims, commonly identifying a user. It lets a server establish identity without treating a cleartext cookie or session identifier as trustworthy. section 7.4.1 section 8.2.4

JWTs address several practical identity problems:

  • Use them when websockets cannot rely on ordinary request headers or cookies to reestablish identity. section 7.4.1
  • Carry identity information in the token itself, reducing dependence on per-request database or session-store lookups. section 8.2.4
  • Treat signing as protection against client spoofing, while remembering that token invalidation remains a significant risk. section 7.4.1 section 8.2.4

Creating and validating a JWT in Go

A Go implementation defines a secret signing key, embeds jwt.RegisteredClaims, sets expiration, issue time, not-before time, and subject, then signs the token with HS256. Use a mature JWT library rather than implementing signing and validation yourself. section 8.2.4

Listing 8.12 Creating and validating JWTs
package main

import (
    "log"
    "time"

    jwt "github.com/golang-jwt/jwt/v5"
)

var SIGNING_KEY = []byte("this-value-should-be-secret"
)   #1

type claim struct {   #2
    jwt.RegisteredClaims
}

func generateClaim() (string, error) {
    claims := claim{
        jwt.RegisteredClaims{
            ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Hour)),
            IssuedAt:  jwt.NewNumericDate(time.Now()),
            NotBefore: jwt.NewNumericDate(time.Now()),
            Subject:   "nobody@example.com",
        },
    }
    token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)   #3
    ss, err := token.SignedString(SIGNING_KEY)                   #3
    if err != nil { #3
        return "", err
    }
    return ss, nil
}

func main() {
    if signed, err := generateClaim(); err != nil {
        panic(err)
    } else {
        token, err := jwt.Parse(signed, func(token *jwt.Token) 
        (interface{}, error) {
            return SIGNING_KEY, nil
        })                            #4
        if err != nil {
            panic(err)
        }
        if validatedClaims, ok := 
        token.Claims.(jwt.MapClaims); ok && token.Valid {    #5
            log.Println(validatedClaims["sub"])
        } else {
            panic("error getting claims")
        }
    }
}

Inspect the complete Go listing for claim construction, signing-key use, expiration timestamps, and token generation. section 8.2.4

How Go in Practice, Second Edition covers it

How deep it goes
Defines claims and demonstrates Go signing with HS256, registered timestamps, and a subject, while deferring custom cryptographic implementation.
Examples
Demonstrates a real-time chat identity problem and a Go token containing subject, expiration, issue-time, and not-before claims.
What it assumes
Assumes familiarity with cookies, sessions, and identity, but introduces JWT claims and signing through a simple Go example.
What you can do after
Apply it via the golang-jwt/jwt library to generate signed identity tokens with registered claims.
How it connects
Connects identity and authentication with websockets, cookies, session identifiers, claims, signing keys, and session stores.

Also explained in

Compare how 11 books explain JSON Web Token →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Go in Practice, Second Edition. The section links point to the parts of the book it draws on.