# JWT 用户类型使用指南 ## 概述 我们定义了完整的JWT类型系统,提供类型安全的JWT操作。 ## 类型定义 ### 1. JwtUserType - JWT中的用户信息 ```typescript interface JwtUserType { userId: number; username: string; email: string; nickname?: string; status: number; role?: string; } ``` ### 2. JwtPayloadType - 完整的JWT载荷 ```typescript interface JwtPayloadType extends JwtUserType { iat: number; // 发行时间 exp: number; // 过期时间 sub?: string; // 主题 iss?: string; // 发行者 aud?: string; // 受众 jti?: string; // JWT ID nbf?: number; // 生效时间 } ``` ## 使用示例 ### 1. 在认证Controller中生成JWT Token ```typescript // auth.controller.ts import { createJwtPayload } from '@/utils/jwt.helper'; import type { UserInfoType } from '@/modules/sample/example.schema'; export const authController = new Elysia() .use(jwtPlugin) .post('/login', async ({ body, jwt }) => { // 用户登录验证逻辑... const userInfo: UserInfoType = await getUserFromDatabase(body.username); // 创建JWT载荷 const payload = createJwtPayload(userInfo, { role: 'user', // 可选的角色信息 issuer: 'my-api', audience: 'web-app', }); // 生成Token const token = await jwt.sign(payload); return { code: 0, message: '登录成功', data: { token, user: payload, // 返回用户信息(不含敏感数据) }, }; }); ``` ### 2. 在需要认证的Controller中使用用户信息 ```typescript // user.controller.ts import { formatUserForLog, isValidJwtUser } from '@/utils/jwt.helper'; import type { JwtUserType } from '@/type/jwt.type'; export const userController = new Elysia() .use(jwtAuthPlugin) .get('/profile', async ({ user, payload }) => { // user 自动推断为 JwtUserType 类型 // payload 自动推断为 JwtPayloadType 类型 // 验证用户有效性 if (!isValidJwtUser(payload)) { Logger.warn(`无效用户尝试访问: ${formatUserForLog(user)}`); return { code: 401, message: '用户状态异常', data: null }; } // 使用类型安全的用户信息 Logger.info(`用户查看个人资料: ${formatUserForLog(user)}`); // 获取完整的用户信息(从数据库) const fullUserInfo = await getUserById(user.userId); return { code: 0, message: '获取成功', data: fullUserInfo, }; }); ``` ### 3. 在Service中使用JWT用户类型 ```typescript // user.service.ts import type { JwtUserType } from '@/type/jwt.type'; export class UserService { // 使用JWT用户类型作为参数 async updateUserProfile(currentUser: JwtUserType, updateData: any) { // 检查权限 if (currentUser.status !== 1) { throw new Error('用户状态异常,无法操作'); } // 更新用户信息 const updatedUser = await db.update(users) .set(updateData) .where(eq(users.id, currentUser.userId)); Logger.info(`用户资料更新: ${currentUser.username} (ID: ${currentUser.userId})`); return updatedUser; } // 根据JWT用户信息获取权限 async getUserPermissions(jwtUser: JwtUserType): Promise { const permissions = await db.select() .from(userPermissions) .where(eq(userPermissions.userId, jwtUser.userId)); return permissions.map(p => p.permission); } } ``` ### 4. Token状态检查 ```typescript // middleware/token-check.ts import { isTokenExpiringSoon, getTokenRemainingTime, formatRemainingTime } from '@/utils/jwt.helper'; export const tokenStatusMiddleware = (app: Elysia) => app.derive(({ payload, user }) => { if (!payload) return {}; // 检查Token是否即将过期 const expiringSoon = isTokenExpiringSoon(payload, 30); // 30分钟阈值 const remainingTime = getTokenRemainingTime(payload); if (expiringSoon) { Logger.warn(`用户Token即将过期: ${user.username}, 剩余时间: ${formatRemainingTime(remainingTime)}`); } return { tokenInfo: { expiringSoon, remainingTime, formattedTime: formatRemainingTime(remainingTime), }, }; }); ``` ### 5. 角色权限检查 ```typescript // middleware/role-check.ts import type { JwtUserType } from '@/type/jwt.type'; export function requireRole(requiredRole: string) { return (app: Elysia) => app.onBeforeHandle(({ user, set }) => { const jwtUser = user as JwtUserType; if (!jwtUser.role || jwtUser.role !== requiredRole) { Logger.warn(`权限不足: 用户${jwtUser.username}尝试访问需要${requiredRole}角色的资源`); set.status = 403; return { code: 403, message: '权限不足', data: null, }; } }); } // 使用示例 export const adminController = new Elysia() .use(jwtAuthPlugin) .use(requireRole('admin')) .get('/admin-only', () => { return { message: '只有管理员能看到这个内容' }; }); ``` ## 🎯 类型安全的好处 1. **编译时检查**: TypeScript 会在编译时检查所有JWT相关操作 2. **智能提示**: IDE 提供完整的属性提示和自动补全 3. **重构安全**: 修改用户类型时,所有相关代码都会得到类型检查 4. **文档作用**: 类型定义本身就是最好的文档 ## 📝 最佳实践 1. **总是使用类型注解**: 在Service方法中明确使用 `JwtUserType` 类型 2. **验证用户状态**: 使用 `isValidJwtUser()` 检查用户有效性 3. **记录操作日志**: 使用 `formatUserForLog()` 格式化用户信息 4. **检查Token状态**: 在关键操作前检查Token是否即将过期 5. **权限分离**: 使用角色字段实现细粒度权限控制