Passkey: 账户设置绑定 + 免密登录(WebAuthn)
- 引入 go-webauthn, Passkey 表存凭据, challenge 会话内存存储(带过期) - API: /webauthn/register|login begin/complete, /webauthn/passkeys 列表/删除 - 配置 OT_WEBAUTHN_RP_ID/RP_ORIGIN/RP_NAME;登录成功发 JWT+refresh cookie - 前端 lib/webauthn(编解码+凭据序列化+安全上下文检测), 账户设置绑定区, 登录页免密按钮 - 需 HTTPS 或 localhost(安全上下文) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -18,9 +18,17 @@ type Config struct {
|
||||
Auth AuthConfig
|
||||
Proxy ProxyConfig
|
||||
RateLimit RateLimitConfig
|
||||
WebAuthn WebAuthnConfig
|
||||
Master string // 渠道密钥 AES-GCM 主密钥(来自环境变量)
|
||||
}
|
||||
|
||||
// WebAuthnConfig Passkey(WebAuthn)配置。
|
||||
type WebAuthnConfig struct {
|
||||
RPID string // Relying Party ID(域名,如 localhost)
|
||||
RPOrigin string // 前端来源,如 http://localhost:5173
|
||||
RPName string // 展示名
|
||||
}
|
||||
|
||||
// RateLimitConfig 限流参数(MVP 内存计数,Redis 后置)。
|
||||
type RateLimitConfig struct {
|
||||
UserRPS int // 用户级每秒请求数上限(0=不限制)
|
||||
@@ -124,6 +132,10 @@ func Load() (*Config, error) {
|
||||
|
||||
v.SetDefault("ratelimit.user_rps", 20)
|
||||
|
||||
v.SetDefault("webauthn.rp_id", "localhost")
|
||||
v.SetDefault("webauthn.rp_origin", "http://localhost:5173")
|
||||
v.SetDefault("webauthn.rp_name", "openteam")
|
||||
|
||||
return &Config{
|
||||
Env: v.GetString("env"),
|
||||
Port: v.GetInt("port"),
|
||||
@@ -160,6 +172,11 @@ func Load() (*Config, error) {
|
||||
RateLimit: RateLimitConfig{
|
||||
UserRPS: v.GetInt("ratelimit.user_rps"),
|
||||
},
|
||||
WebAuthn: WebAuthnConfig{
|
||||
RPID: v.GetString("webauthn.rp_id"),
|
||||
RPOrigin: v.GetString("webauthn.rp_origin"),
|
||||
RPName: v.GetString("webauthn.rp_name"),
|
||||
},
|
||||
Master: v.GetString("master_key"),
|
||||
}, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user