85 lines
3.1 KiB
Go
85 lines
3.1 KiB
Go
package config
|
||
|
||
import (
|
||
"time"
|
||
|
||
"github.com/spf13/viper"
|
||
)
|
||
|
||
type Config struct {
|
||
Server struct {
|
||
Http struct {
|
||
Addr string `mapstructure:"addr"`
|
||
Timeout time.Duration `mapstructure:"timeout"`
|
||
} `mapstructure:"http"`
|
||
Grpc struct {
|
||
Addr string `mapstructure:"addr"`
|
||
Timeout time.Duration `mapstructure:"timeout"`
|
||
} `mapstructure:"grpc"`
|
||
} `mapstructure:"server"`
|
||
Data struct {
|
||
Database struct {
|
||
Driver string `mapstructure:"driver"`
|
||
DSN string `mapstructure:"dsn"`
|
||
} `mapstructure:"database"`
|
||
Redis struct {
|
||
// Mode: standalone(单机)、sentinel(哨兵)、cluster(集群)
|
||
Mode string `mapstructure:"mode"`
|
||
Addr string `mapstructure:"addr"`
|
||
Addrs []string `mapstructure:"addrs"`
|
||
Password string `mapstructure:"password"`
|
||
Username string `mapstructure:"username"`
|
||
DB int `mapstructure:"db"`
|
||
MasterName string `mapstructure:"master_name"`
|
||
PoolSize int `mapstructure:"pool_size"`
|
||
// MinIdleConns 最小空闲连接数
|
||
MinIdleConns int `mapstructure:"min_idle_conns"`
|
||
MaxRetries int `mapstructure:"max_retries"`
|
||
RetryDelay time.Duration `mapstructure:"retry_delay"`
|
||
RetryMaxDelay time.Duration `mapstructure:"retry_max_delay"`
|
||
DialTimeout time.Duration `mapstructure:"dial_timeout"`
|
||
ReadTimeout time.Duration `mapstructure:"read_timeout"`
|
||
WriteTimeout time.Duration `mapstructure:"write_timeout"`
|
||
// IdleTimeout 映射为 go-redis ConnMaxIdleTime
|
||
IdleTimeout time.Duration `mapstructure:"idle_timeout"`
|
||
} `mapstructure:"redis"`
|
||
} `mapstructure:"data"`
|
||
// Auth 认证域(OAuth2、会话等);PublicBaseURL 为浏览器可访问的后端根 URL(用于登录回跳拼接 /oauth/authorize)
|
||
Auth struct {
|
||
PublicBaseURL string `mapstructure:"public_base_url"`
|
||
OAuth2 struct {
|
||
FrontendLoginURL string `mapstructure:"frontend_login_url"`
|
||
AuthCodeTTL time.Duration `mapstructure:"auth_code_ttl"`
|
||
AccessTokenTTL time.Duration `mapstructure:"access_token_ttl"`
|
||
RefreshTokenTTL time.Duration `mapstructure:"refresh_token_ttl"`
|
||
} `mapstructure:"oauth2"`
|
||
Session struct {
|
||
CookieName string `mapstructure:"cookie_name"`
|
||
CookieDomain string `mapstructure:"cookie_domain"`
|
||
CookieSecure bool `mapstructure:"cookie_secure"`
|
||
SameSite string `mapstructure:"same_site"` // lax, strict, none
|
||
TTL time.Duration `mapstructure:"ttl"`
|
||
} `mapstructure:"session"`
|
||
// RateLimit 登录与令牌端点限流(进程内按 IP;多实例需网关或 Redis 限流)
|
||
RateLimit struct {
|
||
Enabled bool `mapstructure:"enabled"`
|
||
LoginPerMinute int `mapstructure:"login_per_minute"`
|
||
TokenPerMinute int `mapstructure:"token_per_minute"`
|
||
} `mapstructure:"rate_limit"`
|
||
} `mapstructure:"auth"`
|
||
}
|
||
|
||
// 加载配置文件
|
||
func Load(path string) (*Config, error) {
|
||
v := viper.New()
|
||
v.SetConfigFile(path)
|
||
if err := v.ReadInConfig(); err != nil {
|
||
return nil, err
|
||
}
|
||
var config Config
|
||
if err := v.Unmarshal(&config); err != nil {
|
||
return nil, err
|
||
}
|
||
return &config, nil
|
||
}
|