Change authcode using redis, authtoken use client secret to sign jwt
Some checks failed
Build Backend (NixCN CMS) TeamCity build failed
Build Frontend (NixCN CMS) TeamCity build finished

Signed-off-by: Asai Neko <sugar@sne.moe>
This commit is contained in:
2026-01-05 21:59:37 +08:00
parent aea7fddef0
commit b0684492fa
5 changed files with 179 additions and 91 deletions

View File

@@ -1,53 +1,68 @@
package authcode
import (
"context"
"crypto/rand"
"encoding/base64"
"sync"
"time"
"nixcn-cms/data"
"github.com/spf13/viper"
)
type Token struct {
Email string
ExpiresAt time.Time
ClientId string
Email string
}
var (
store = sync.Map{}
)
func NewAuthCode(clientId string, email string) (string, error) {
ctx := context.Background()
// Generate magic token
func NewAuthCode(email string) (string, error) {
// 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
store.Store(code, Token{
Email: email,
ExpiresAt: time.Now().Add(viper.GetDuration("ttl.auth_code_ttl")),
})
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
}
// Verify magic token
func VerifyAuthCode(code string) (string, bool) {
val, ok := store.Load(code)
if !ok {
return "", false
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
}
t := val.(Token)
if time.Now().After(t.ExpiresAt) {
store.Delete(code)
return "", false
}
// Delete auth code immediately (one-time use)
_ = data.Redis.Del(ctx, key).Err()
store.Delete(code)
return t.Email, true
return &Token{
ClientId: dataMap["client_id"],
Email: dataMap["email"],
}, true
}