feat(security): HttpOnly cookie sessions, token revocation, and RBAC

- Add User.role (enum Role/ADMIN) and User.tokenVersion with migration
- Login now issues short-lived access token (30m default) + 7d refresh
  token, both embedding tokenVersion and a typ discriminator
- Tokens delivered via HttpOnly SameSite cookies (ir_at, ir_rt scoped
  to /auth); refresh token never leaves the cookie
- New endpoints: POST /auth/refresh (rotation), GET /auth/me,
  POST /auth/logout (bumps tokenVersion, revoking all tokens)
- JWT strategy accepts bearer or cookie, rejects refresh tokens, and
  verifies tokenVersion + user existence on every request
- Global RolesGuard: authenticated routes require ADMIN unless widened
  via @Roles(...)
- Admin SPA: session fully cookie-based, no token in localStorage;
  router guard restores session via /auth/me; axios auto-refreshes once
  on 401; stale localStorage keys cleaned up
This commit is contained in:
yeuimu
2026-08-22 12:04:56 +08:00
parent 755b40aded
commit be0b90e68f
16 changed files with 503 additions and 85 deletions
+2
View File
@@ -41,6 +41,7 @@
"bcrypt": "^5.1.1",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.0",
"cookie-parser": "^1.4.7",
"express": "^4.21.0",
"helmet": "^8.3.0",
"multer": "^2.2.0",
@@ -54,6 +55,7 @@
"@nestjs/schematics": "^10.0.3",
"@nestjs/testing": "^10.3.0",
"@types/bcrypt": "^5.0.2",
"@types/cookie-parser": "^1.4.10",
"@types/express": "^4.17.21",
"@types/jest": "^29.5.11",
"@types/node": "^20.10.6",