Documentation
¶
Overview ¶
Package nonce provides middleware that generates a fresh, random, base64-encoded nonce for each request. It mirrors the Node helpers built around Content-Security-Policy nonces — for example express's res.locals nonce pattern and the cspNonce/helmet-csp integration used to authorize specific inline scripts and styles — by producing one unguessable token per request that downstream code can attach to a CSP header and to markup.
Reach for it whenever you need a per-request nonce, most commonly to allow a handful of trusted inline <script>/<style> blocks under a strict CSP without resorting to 'unsafe-inline'. Because a nonce is only safe if it is fresh and unpredictable for every response, this middleware regenerates it on each request rather than reusing a value; templates and a CSP builder then read the same token so the header and the markup agree.
It should run early in the chain, before any CSP-setting middleware and before your view renders. On each request it calls Generate to produce the token, then publishes it in two places so both worlds can see it: req.Set(ContextKey, n) for downstream Go handlers (retrievable with Nonce) and res.Locals[ContextKey] for templates. It writes no response headers itself and always calls next() to continue the chain — wiring the nonce into an actual CSP header is the job of a separate middleware or your route.
The token is built with crypto/rand and base64-standard encoded. Options.Bytes controls the entropy and defaults to 16 bytes when unset or non-positive, which after base64 yields a comfortably unguessable string. ContextKey is the fixed lookup key ("nonce") shared by the request store and Locals. One edge case to know: if the system random source fails, Generate returns an empty string rather than panicking, so a defensive CSP builder should treat "" as "no nonce available"; Nonce likewise returns "" when the middleware never ran or stored a non-string value.
Parity with the Node original is behavioral rather than byte-for-byte. Like the common express nonce recipe it exposes the value through res.Locals and generates cryptographically strong randomness per request; the base64 alphabet and default byte count match the widely used defaults. It intentionally stops at producing and publishing the nonce, leaving header composition to the csp/ cspnonce middleware so the two concerns stay decoupled.
Index ¶
Examples ¶
Constants ¶
const ContextKey = "nonce"
ContextKey is the key under which the generated nonce is stored on the request and in res.Locals.
Variables ¶
This section is empty.
Functions ¶
func New ¶
New returns middleware that stores a per-request random nonce via req.Set("nonce", n) and res.Locals["nonce"]. Retrieve it with Nonce.
Example ¶
ExampleNew installs the nonce middleware and demonstrates that a fresh token is published for the request. The middleware is registered globally with app.Use so it runs before the route handler. Inside the handler the nonce is read back with nonce.Nonce(req) and also from res.Locals, showing the two publication sites agree. The request is driven in-memory with httptest.NewRequest and a recorder via app.ServeHTTP. Because the token is random its value is not asserted; instead the example prints only whether a non-empty nonce was generated and matched, keeping the output deterministic.
package main
import (
"fmt"
"net/http"
"net/http/httptest"
"github.com/malcolmston/express"
"github.com/malcolmston/express/middleware/nonce"
)
func main() {
app := express.New()
app.Use(nonce.New(nonce.Options{Bytes: 16}))
app.Get("/", func(req *express.Request, res *express.Response, next express.Next) {
fromReq := nonce.Nonce(req)
fromLocals, _ := res.Locals[nonce.ContextKey].(string)
fmt.Println(fromReq != "" && fromReq == fromLocals)
res.Send("ok")
})
rec := httptest.NewRecorder()
app.ServeHTTP(rec, httptest.NewRequest(http.MethodGet, "/", nil))
}
Output: true