package auth import ( "crypto/hmac" "crypto/sha256" "encoding/hex" "fmt" ) // CSRFToken derives a per-user token from the secret; it changes whenever the // user's token_version changes (password reset, disable) and needs no storage. func CSRFToken(secret []byte, userID int64, tokenVersion int) string { m := hmac.New(sha256.New, secret) fmt.Fprintf(m, "csrf:%d:%d", userID, tokenVersion) return hex.EncodeToString(m.Sum(nil)) } func CheckCSRF(secret []byte, userID int64, tokenVersion int, got string) bool { return hmac.Equal([]byte(CSRFToken(secret, userID, tokenVersion)), []byte(got)) }