or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

bpf.mdcontext-ctxhttp.mdcontext.mddict.mddns-dnsmessage.mdhtml-atom.mdhtml-charset.mdhtml.mdhttp-httpguts.mdhttp-httpproxy.mdhttp2-h2c.mdhttp2-hpack.mdhttp2.mdicmp.mdidna.mdindex.mdipv4.mdipv6.mdnettest.mdnetutil.mdproxy.mdpublicsuffix.mdquic-qlog.mdquic.mdtrace.mdwebdav.mdwebsocket.mdxsrftoken.md
tile.json

xsrftoken.mddocs/

XSRF Token Generation

Package xsrftoken provides methods for generating and validating secure XSRF tokens.

Import

import "golang.org/x/net/xsrftoken"

Constants

// Timeout is the duration for which XSRF tokens are valid
const Timeout = 24 * time.Hour

Timeout is exported so clients may set cookie timeouts that match generated tokens.

Functions

// Generate returns a URL-safe secure XSRF token that expires in 24 hours
func Generate(key, userID, actionID string) string

// Valid reports whether a token is valid and unexpired
func Valid(token, key, userID, actionID string) bool

// ValidFor reports whether a token is valid with a custom timeout
func ValidFor(token, key, userID, actionID string, timeout time.Duration) bool

Generate

Generate returns a URL-safe secure XSRF token that expires in 24 hours.

  • key: A secret key for your application (must be non-empty)
  • userID: An optional unique identifier for the user
  • actionID: An optional action the user is taking (e.g., POSTing to a particular path)

Valid

Valid reports whether a token is a valid, unexpired token returned by Generate. The token is considered expired and invalid if it is older than the default Timeout (24 hours).

ValidFor

ValidFor reports whether a token is a valid, unexpired token returned by Generate with a custom timeout duration. The token is considered expired and invalid if it is older than the specified timeout.

Usage Examples

Basic XSRF Protection

import (
    "golang.org/x/net/xsrftoken"
    "net/http"
)

const secretKey = "your-secret-key-here"

func renderForm(w http.ResponseWriter, r *http.Request, userID string) {
    // Generate XSRF token
    token := xsrftoken.Generate(secretKey, userID, "POST /submit")

    // Include token in form
    html := `
        <form method="POST" action="/submit">
            <input type="hidden" name="xsrf_token" value="` + token + `">
            <input type="text" name="data">
            <button type="submit">Submit</button>
        </form>
    `

    w.Write([]byte(html))
}

func handleSubmit(w http.ResponseWriter, r *http.Request, userID string) {
    // Validate XSRF token
    token := r.FormValue("xsrf_token")

    if !xsrftoken.Valid(token, secretKey, userID, "POST /submit") {
        http.Error(w, "Invalid XSRF token", http.StatusForbidden)
        return
    }

    // Process form submission
    // ...
}

With Cookies

func setXSRFCookie(w http.ResponseWriter, userID string) string {
    token := xsrftoken.Generate(secretKey, userID, "")

    // Set cookie with matching timeout
    http.SetCookie(w, &http.Cookie{
        Name:     "xsrf_token",
        Value:    token,
        MaxAge:   int(xsrftoken.Timeout.Seconds()),
        HttpOnly: true,
        Secure:   true,
        SameSite: http.SameSiteStrictMode,
    })

    return token
}

func validateXSRFCookie(r *http.Request, userID string) bool {
    cookie, err := r.Cookie("xsrf_token")
    if err != nil {
        return false
    }

    return xsrftoken.Valid(cookie.Value, secretKey, userID, "")
}

Per-Action Tokens

func generateActionToken(userID, action string) string {
    // Generate token specific to user and action
    return xsrftoken.Generate(secretKey, userID, action)
}

func validateActionToken(token, userID, action string) bool {
    return xsrftoken.Valid(token, secretKey, userID, action)
}

// Usage:
// token := generateActionToken("user123", "POST /delete")
// valid := validateActionToken(token, "user123", "POST /delete")

Custom Timeout

import "time"

func generateShortLivedToken(userID string) string {
    return xsrftoken.Generate(secretKey, userID, "quick-action")
}

func validateShortLivedToken(token, userID string) bool {
    // Validate with 5-minute timeout instead of default 24 hours
    return xsrftoken.ValidFor(token, secretKey, userID, "quick-action", 5*time.Minute)
}

Middleware Pattern

func XSRFMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        userID := getUserID(r) // Get user ID from session/auth

        if r.Method == "GET" {
            // For GET requests, generate and set token
            token := xsrftoken.Generate(secretKey, userID, r.URL.Path)
            r = r.WithContext(context.WithValue(r.Context(), "xsrf_token", token))
        } else {
            // For POST/PUT/DELETE, validate token
            token := r.Header.Get("X-XSRF-Token")
            if token == "" {
                token = r.FormValue("xsrf_token")
            }

            if !xsrftoken.Valid(token, secretKey, userID, r.URL.Path) {
                http.Error(w, "Invalid XSRF token", http.StatusForbidden)
                return
            }
        }

        next.ServeHTTP(w, r)
    })
}