- access token 是 15 分钟的 JWT,走 Authorization: Bearer;refresh token 7 天,每次换都轮换 - 退出登录、改密码、禁用账号仍然立刻生效:每个请求核对 Redis 会话和库里新加的 user.token_version - 在服务器后台改密码 / 禁用,机房那边登着的也会一起下线(原来两边 Redis 分开,管不到) - WebSocket 握手借子协议带 token;JWT 密钥存在本站 Redis,部署不用加配置 - 去掉 COOKIE_SECURE;上线后所有人要重新登录一次 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
4be569d978
commit
793848b06f
31 files changed
+4639
-333
No files matched your search
@@ -67,9 +67,6 @@ WEB_PORT=
|
||||
JUDGE_STATE_DIR=
|
||||
|
||||
# --- 只有机房那套需要 ---
|
||||
# 机房走 http 直连 IP,没有 TLS,必须 false,否则 Cookie 发不回来。
|
||||
COOKIE_SECURE=false
|
||||
|
||||
# 机房没有本地库,连服务器的 5445。不填时默认指向服务器(默认值在 compose.school.yml 里),
|
||||
# 换服务器才要填。服务器那套不读这两个。
|
||||
DB_HOST=
|
||||
|
||||
+16
-18
@@ -1,17 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# 一次性运维动作:清掉所有会话,强制全员重新登录。
|
||||
# 运维动作:清掉所有会话,强制全员重新登录。
|
||||
#
|
||||
# ## 为什么要跑
|
||||
# 会话是 `auth-session:<sid>`(见 apps/api/src/auth/session.ts),删掉之后 access token
|
||||
# 下一个请求就不认、refresh token 也换不出新的,不用等 token 自然过期。
|
||||
# 顺带清掉 cookie 时代留下的 `session:*` / `user-sessions:*`(换成 token 之后没人读了,
|
||||
# 不清的话也会在 7 天内自己过期)。
|
||||
#
|
||||
# 会话的反向索引 `user-sessions:<uid>` 是 498fc1c 才加的。在那之前签发的会话不在索引
|
||||
# 里,revokeUserSessions 靠 SMEMBERS 找不到它们 —— 也就是说**改密码、重置密码、禁用
|
||||
# 账号对这批会话统统无效**,只能等最长一个 SESSION_TTL_SECONDS(默认 7 天)自然过期。
|
||||
#
|
||||
# 学生密码是明文存着给老师查的,改密码正是密码泄露之后唯一的补救手段,这个空窗不能留。
|
||||
# 代价只是所有人重新登录一次。
|
||||
#
|
||||
# 跑过一次就不用再跑了:此后签发的会话都带索引。
|
||||
# 只想让某一个人下线不用跑这个:后台改密码 / 禁用账号就会把他所有设备踢下线。
|
||||
#
|
||||
# ## 两个站点都要跑
|
||||
#
|
||||
@@ -23,7 +19,7 @@
|
||||
# 同一个 Redis 里还装着 BullMQ 的判题队列(`bull:*`)。FLUSHALL 会把还在队列里的提交
|
||||
# 一起丢掉,那些 submission 会永远停在 PENDING,只能超管逐条重判 —— 而重判还会把
|
||||
# user_profile 的反范式计数带偏(见 apps/api/src/scripts/recount.ts)。
|
||||
# 这里只删 `session:*` 和 `user-sessions:*`。
|
||||
# 这里只删下面列出来的几种会话键。
|
||||
#
|
||||
# ## 用法
|
||||
#
|
||||
@@ -70,13 +66,14 @@ purge() {
|
||||
|
||||
count() { cli --scan --pattern "$1" 2>/dev/null | wc -l; }
|
||||
|
||||
PATTERNS=('auth-session:*' 'auth-contest:*' 'session:*' 'user-sessions:*')
|
||||
|
||||
say "容器 $CONTAINER"
|
||||
before_sessions=$(count 'session:*')
|
||||
before_index=$(count 'user-sessions:*')
|
||||
for pattern in "${PATTERNS[@]}"; do
|
||||
printf ' %-16s %s\n' "$pattern" "$(count "$pattern")"
|
||||
done
|
||||
before_bull=$(count 'bull:*')
|
||||
printf ' session:* %s\n' "$before_sessions"
|
||||
printf ' user-sessions:* %s\n' "$before_index"
|
||||
printf ' bull:* %s(不动)\n' "$before_bull"
|
||||
printf ' %-16s %s(不动)\n' 'bull:*' "$before_bull"
|
||||
|
||||
if [ "${YES:-}" != "1" ]; then
|
||||
read -rp $'\n 删掉上面的会话、让所有人重新登录?[y/N] ' answer
|
||||
@@ -84,8 +81,9 @@ if [ "${YES:-}" != "1" ]; then
|
||||
fi
|
||||
|
||||
say "清理"
|
||||
ok "session:* 删掉 $(purge 'session:*') 个"
|
||||
ok "user-sessions:* 删掉 $(purge 'user-sessions:*') 个"
|
||||
for pattern in "${PATTERNS[@]}"; do
|
||||
ok "$(printf '%-16s' "$pattern") 删掉 $(purge "$pattern") 个"
|
||||
done
|
||||
|
||||
after_bull=$(count 'bull:*')
|
||||
[ "$after_bull" = "$before_bull" ] \
|
||||
|
||||
@@ -151,8 +151,6 @@ services:
|
||||
TRIAL_CONCURRENCY: ${TRIAL_CONCURRENCY:-2}
|
||||
AI_KEY: ${AI_KEY:-}
|
||||
AI_HINT_DIAGNOSE: ${AI_HINT_DIAGNOSE:-}
|
||||
# 走 NPM 终止 TLS,浏览器侧是 https,Cookie 必须带 Secure
|
||||
COOKIE_SECURE: "true"
|
||||
healthcheck:
|
||||
test: ["CMD", "oj2-api", "healthcheck"]
|
||||
interval: 30s
|
||||
|
||||
@@ -85,9 +85,6 @@ services:
|
||||
TRIAL_CONCURRENCY: ${TRIAL_CONCURRENCY:-4}
|
||||
AI_KEY: ${AI_KEY:-}
|
||||
AI_HINT_DIAGNOSE: ${AI_HINT_DIAGNOSE:-}
|
||||
# 机房走 http 直连 IP,没有 TLS。带 Secure 的 Cookie 浏览器不会回传,
|
||||
# 学生会「登录成功但立刻又是未登录」。这里必须是 false。
|
||||
COOKIE_SECURE: ${COOKIE_SECURE:-false}
|
||||
healthcheck:
|
||||
test: ["CMD", "oj2-api", "healthcheck"]
|
||||
interval: 30s
|
||||
|
||||
Reference in new issue
Block a user