package dingtalk import ( "context" "errors" "fmt" "time" redisLib "github.com/go-redis/redis/v8" ) // redisTokenStorage 用 go-redis 实现的 TokenStorage type redisTokenStorage struct { cli *redisLib.Client keyPrefix string } // NewRedisTokenStorage 基于 *redisLib.Client 构造 TokenStorage // keyPrefix 默认:"dingtalk:access_token:" func NewRedisTokenStorage(cli *redisLib.Client, keyPrefix string) TokenStorage { if keyPrefix == "" { keyPrefix = "dingtalk:access_token:" } return &redisTokenStorage{cli: cli, keyPrefix: keyPrefix} } func (r *redisTokenStorage) key(clientID string) string { return fmt.Sprintf("%s%s", r.keyPrefix, clientID) } // GetToken 从 Redis 读取 token;未命中返回 ("", nil) func (r *redisTokenStorage) GetToken(ctx context.Context, clientID string) (string, error) { if r.cli == nil { return "", nil } val, err := r.cli.Get(ctx, r.key(clientID)).Result() if err != nil { if errors.Is(err, redisLib.Nil) { return "", nil } return "", err } return val, nil } // SetToken 写入 Redis,ttl<=0 时删除该 key func (r *redisTokenStorage) SetToken(ctx context.Context, clientID, token string, ttl time.Duration) error { if r.cli == nil { return nil } if token == "" || ttl <= 0 { return r.cli.Del(ctx, r.key(clientID)).Err() } return r.cli.Set(ctx, r.key(clientID), token, ttl).Err() }