package model import ( "crypto/rand" "crypto/sha256" "crypto/subtle" "encoding/base64" ) func NewVisitorToken() (string, string, error) { bytes := make([]byte, 32) if _, err := rand.Read(bytes); err != nil { return "", "", err } token := base64.RawURLEncoding.EncodeToString(bytes) return token, HashVisitorToken(token), nil } func HashVisitorToken(token string) string { hash := sha256.Sum256([]byte(token)) return base64.RawURLEncoding.EncodeToString(hash[:]) } func VerifyVisitorToken(session *Session, token string) bool { if token == "" || session.VisitorTokenHash == "" { return false } return subtle.ConstantTimeCompare([]byte(session.VisitorTokenHash), []byte(HashVisitorToken(token))) == 1 }