package authcode import ( "context" "crypto/rand" "encoding/base64" "nixcn-cms/data" "github.com/spf13/viper" ) type Token struct { ClientId string Email string } func NewAuthCode(clientId string, email string) (string, error) { ctx := context.Background() // generate random code b := make([]byte, 32) if _, err := rand.Read(b); err != nil { return "", err } code := base64.RawURLEncoding.EncodeToString(b) key := "auth_code:" + code ttl := viper.GetDuration("ttl.auth_code_ttl") // store auth code metadata in Redis if err := data.Redis.HSet( ctx, key, map[string]any{ "client_id": clientId, "email": email, }, ).Err(); err != nil { return "", err } // set expiration (one-time auth code) if err := data.Redis.Expire(ctx, key, ttl).Err(); err != nil { return "", err } return code, nil } func VerifyAuthCode(code string) (*Token, bool) { ctx := context.Background() key := "auth_code:" + code // Read auth code payload dataMap, err := data.Redis.HGetAll(ctx, key).Result() if err != nil || len(dataMap) == 0 { return nil, false } // Delete auth code immediately (one-time use) _ = data.Redis.Del(ctx, key).Err() return &Token{ ClientId: dataMap["client_id"], Email: dataMap["email"], }, true }