Files
Blizzard bffdb3858b
Checks / verify (push) Failing after 2m37s
feat: 基础框架搭建完毕
2026-10-07 09:27:47 +08:00

35 lines
991 B
Go

package ratelimit
import (
"context"
"crypto/sha256"
"fmt"
"github.com/redis/go-redis/v9"
)
type Redis struct{ client *redis.Client }
func NewRedis(client *redis.Client) *Redis { return &Redis{client: client} }
var loginCounter = redis.NewScript(`local n = redis.call('INCR', KEYS[1]); if n == 1 then redis.call('EXPIRE', KEYS[1], 900) end; return n`)
// Login permits at most 20 attempts per IP and 10 per login in a 15-minute window.
// Redis errors fail closed. Neither credential nor IP is stored in plaintext keys.
func (r *Redis) Login(ctx context.Context, ip, login string) (bool, error) {
for _, item := range []struct {
kind, value string
limit int64
}{{"ip", ip, 20}, {"name", login, 10}} {
key := fmt.Sprintf("veyra:login:%s:%x", item.kind, sha256.Sum256([]byte(item.value)))
n, err := loginCounter.Run(ctx, r.client, []string{key}).Int64()
if err != nil {
return false, err
}
if n > item.limit {
return false, nil
}
}
return true, nil
}