登录改用访问令牌 + 刷新令牌,不用 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
@@ -1,6 +1,6 @@
|
||||
// 班级和学生名单(老师用)。学生账号由老师上传名单导入,密码由老师发放,学生不能自己改。
|
||||
import type { Database } from 'bun:sqlite'
|
||||
import { endSessions } from './auth'
|
||||
import { revokeTokens } from './auth'
|
||||
|
||||
export interface ClassInfo {
|
||||
id: number
|
||||
@@ -115,7 +115,7 @@ export function importStudents(db: Database, classId: number, rows: ImportRow[])
|
||||
}
|
||||
if (existing) {
|
||||
update.run(name, classId, password ?? null, existing.id)
|
||||
if (password) endSessions(db, existing.id)
|
||||
if (password) revokeTokens(db, existing.id)
|
||||
result.updated++
|
||||
} else {
|
||||
insert.run(username, name, password ?? generatePassword(), classId, Date.now())
|
||||
@@ -131,11 +131,11 @@ export function resetPassword(db: Database, studentId: number): string | null {
|
||||
const password = generatePassword()
|
||||
const changed = db.query(`UPDATE users SET password = ? WHERE id = ? AND role = 'student'`).run(password, studentId).changes
|
||||
if (!changed) return null
|
||||
endSessions(db, studentId)
|
||||
revokeTokens(db, studentId)
|
||||
return password
|
||||
}
|
||||
|
||||
/** 删除学生,连同他的作品和登录会话 */
|
||||
/** 删除学生,连同他的作品 */
|
||||
export function deleteStudent(db: Database, studentId: number) {
|
||||
db.query(`DELETE FROM users WHERE id = ? AND role = 'student'`).run(studentId)
|
||||
}
|
||||
Reference in new issue
Block a user