登录改用访问令牌 + 刷新令牌,不用 cookie
- 访问令牌:JWT(HS256),15 分钟,Authorization: Bearer;WebSocket 放在网址参数里 - 刷新令牌:30 天,每次刷新换新的,数据库只存哈希;退出登录即作废 - 重置密码、删除学生:令牌版本加一并删除刷新令牌,所有设备立即退出 - 签名密钥首次使用时生成,存在数据库 settings 表 - 浏览器:令牌存 localStorage;快过期先刷新,401 时刷新一次再重试;多个标签页同时刷新不冲突 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
a3eb563b70
commit
5bb2940969
11 files changed
+332
-110
No files matched your search
+6
-4
@@ -1,6 +1,6 @@
|
||||
import type { ClientMessage, ServerMessage } from '@iot/shared'
|
||||
import { createApp } from './app'
|
||||
import { ensureTeacher, sessionToken, sessionUser } from './auth'
|
||||
import { ensureTeacher, tokenUser } from './auth'
|
||||
import { compileService } from './compile-service'
|
||||
import { config } from './config'
|
||||
import { openDatabase } from './db'
|
||||
@@ -21,9 +21,11 @@ interface SocketData {
|
||||
|
||||
const server = Bun.serve({
|
||||
port: config.port,
|
||||
fetch(req, server) {
|
||||
if (new URL(req.url).pathname === '/ws') {
|
||||
if (!sessionUser(db, sessionToken(req.headers.get('cookie')))) return new Response('请先登录', { status: 401 })
|
||||
async fetch(req, server) {
|
||||
const url = new URL(req.url)
|
||||
if (url.pathname === '/ws') {
|
||||
// 浏览器的 WebSocket 不能带请求头,令牌放在网址参数里
|
||||
if (!(await tokenUser(db, url.searchParams.get('token')))) return new Response('请先登录', { status: 401 })
|
||||
if (server.upgrade(req, { data: {} })) return
|
||||
return new Response('WebSocket 升级失败', { status: 400 })
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user