Pronoun card website and API
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

45 lines
1.1 KiB

package auth
import (
// numStates is the number of CSRF states stored in Redis at any one time.
// This must be an integer.
const numStates = "1000"
// setCSRFState generates a random string to use as state, then stores that in Redis.
func (s *Server) setCSRFState(ctx context.Context) (string, error) {
state := RandBase64(32)
err := s.DB.MultiCmd(ctx,
radix.Cmd(nil, "LPUSH", "csrf", state),
radix.Cmd(nil, "LTRIM", "csrf", "0", numStates),
return state, err
// validateCSRFState checks if the given state exists in Redis.
func (s *Server) validateCSRFState(ctx context.Context, state string) (matched bool, err error) {
var num int
err = s.DB.Redis.Do(ctx, radix.Cmd(&num, "LREM", "csrf", "1", state))
if err != nil {
return num > 0, nil
// RandBase64 returns a string of random bytes encoded in raw base 64.
func RandBase64(size int) string {
b := make([]byte, size)
_, err := rand.Read(b)
if err != nil {
return base64.RawURLEncoding.EncodeToString(b)