Change authcode using redis, authtoken use client secret to sign jwt
Signed-off-by: Asai Neko <sugar@sne.moe>
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user