mirror of
https://github.com/Buriburizaem0n/nezha_domains.git
synced 2026-09-21 02:30:14 +00:00
feat(jwt): server-side session table with keyId + obfuscated uid claims
Replace the {user_id, ip} claim pair with {keyId, uid}:
- keyId is a 32-byte random id that points to a row in the new
jwt_sessions table holding the real user id, bound IP, UA hash,
TokenVersion and expiry.
- uid is the user id encoded through pkg/idcodec; mismatch between
claim uid and session.UserID trips WAF block on the caller IP.
- identityHandler now rejects unknown/revoked/expired sessions, IP
drift and stale TokenVersion. Refresh updates session.ExpiresAt.
User.TokenVersion bumps on password change and revokes outstanding
sessions, so a leaked JWT secret alone is no longer enough to forge
a token. JWTSession rows are GC'd every 10 minutes (expired + grace
or revoked >24h). OAuth2 callback shares the same issue path.
Includes regression tests for happy path, mismatched claim uid,
revoked session, TokenVersion bump, IP drift and unknown keyId.
Co-authored-by: cloudcode <cloudcode@users.noreply.github.com>
This commit is contained in:
+13
-7
@@ -24,15 +24,16 @@ import (
|
||||
"github.com/nezhahq/nezha/cmd/dashboard/controller/waf"
|
||||
"github.com/nezhahq/nezha/cmd/dashboard/rpc"
|
||||
"github.com/nezhahq/nezha/model"
|
||||
"github.com/nezhahq/nezha/pkg/idcodec"
|
||||
"github.com/nezhahq/nezha/pkg/utils"
|
||||
"github.com/nezhahq/nezha/proto"
|
||||
"github.com/nezhahq/nezha/service/singleton"
|
||||
)
|
||||
|
||||
type DashboardCliParam struct {
|
||||
Version bool // 当前版本号
|
||||
ConfigFile string // 配置文件路径
|
||||
DatabaseLocation string // Sqlite3 数据库文件路径
|
||||
Version bool
|
||||
ConfigFile string
|
||||
DatabaseLocation string
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -42,7 +43,6 @@ var (
|
||||
)
|
||||
|
||||
func initSystem(bus chan<- *model.Service) error {
|
||||
// 初始化管理员账户
|
||||
var usersCount int64
|
||||
if err := singleton.DB.Model(&model.User{}).Count(&usersCount).Error; err != nil {
|
||||
return err
|
||||
@@ -61,23 +61,28 @@ func initSystem(bus chan<- *model.Service) error {
|
||||
}
|
||||
}
|
||||
|
||||
// 启动 singleton 包下的所有服务
|
||||
if err := singleton.LoadSingleton(bus); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 每天的3:30 对流量记录进行清理
|
||||
if _, err := singleton.CronShared.AddFunc("0 30 3 * * *", singleton.CleanMonitorHistory); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 每小时对流量记录进行打点
|
||||
if _, err := singleton.CronShared.AddFunc("0 0 * * * *", func() { singleton.RecordTransferHourlyUsage() }); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := singleton.StartJWTSessionGC(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func initIDCodec() error {
|
||||
return idcodec.Init([]byte(singleton.Conf.JWTSecretKey))
|
||||
}
|
||||
|
||||
// @title Nezha Monitoring API
|
||||
// @version 1.0
|
||||
// @description Nezha Monitoring API
|
||||
@@ -113,6 +118,7 @@ func main() {
|
||||
serviceSentinelDispatchBus := make(chan *model.Service)
|
||||
if err := utils.FirstError(singleton.InitFrontendTemplates,
|
||||
func() error { return singleton.InitConfigFromPath(dashboardCliParam.ConfigFile) },
|
||||
initIDCodec,
|
||||
singleton.InitTimezoneAndCache,
|
||||
func() error {
|
||||
if singleton.Conf.Memory.GoMemLimitMB > 0 {
|
||||
|
||||
Reference in New Issue
Block a user