添加jwt验证,添加交叉评查首页加载对接接口,评查任务文档列表对接接口,意见列表对接接口

This commit is contained in:
2025-07-22 14:37:37 +08:00
parent de953283e3
commit 47664fc0e8
19 changed files with 1988 additions and 557 deletions
+204
View File
@@ -0,0 +1,204 @@
# JWT 认证系统实现说明
## 概述
本项目实现了一个基于JWT的前端认证系统,配合OAuth2.0统一认证使用。该系统在用户通过OAuth2.0认证后,生成一个前端专用的JWT Token,包含用户信息和权限数据。
## 核心功能
### 1. JWT生成与管理 (`app/utils/jwt.ts`)
- 生成包含用户信息的JWT
- 验证JWT的有效性
- 检查JWT过期状态
- 解析JWT获取用户信息
### 2. 认证服务集成 (`app/api/login/auth.server.ts`)
- 在OAuth2.0登录成功后自动生成JWT
- 在Token刷新时重新生成JWT
- JWT自动存储在session中
### 3. 前端认证Hook (`app/hooks/useAuth.ts`)
- 提供便捷的认证状态获取
- JWT验证和过期检查
- 用户权限检查功能
## 使用方法
### 在Loader中返回认证信息
```typescript
// app/routes/your-route.tsx
export async function loader({ request }: LoaderFunctionArgs) {
const { getUserSession } = await import("~/api/login/auth.server");
const sessionData = await getUserSession(request);
return Response.json({
// 你的其他数据
yourData: "...",
// 认证信息
isAuthenticated: sessionData.isAuthenticated,
userInfo: sessionData.userInfo,
userRole: sessionData.userRole,
frontendJWT: sessionData.frontendJWT
});
}
```
### 在组件中使用认证信息
```typescript
// 在你的React组件中
import { useAuth } from '~/hooks/useAuth';
export default function YourComponent() {
const auth = useAuth();
// 检查认证状态
if (!auth.isAuthenticated) {
return <div></div>;
}
// 使用用户信息
return (
<div>
<h1>{auth.nickName}</h1>
<p>ID: {auth.userId}</p>
<p>: {auth.userRole}</p>
{/* 权限检查 */}
{auth.isAdmin() && (
<button></button>
)}
{auth.hasRole('developer') && (
<button></button>
)}
</div>
);
}
```
### JWT验证和状态检查
```typescript
const auth = useAuth();
// 验证JWT
const jwtValidation = auth.validateJWT();
if (!jwtValidation.valid) {
console.error('JWT无效:', jwtValidation.error);
}
// 检查是否即将过期
if (auth.isJWTExpiringSoon()) {
console.log('JWT即将过期,建议刷新页面');
}
// 获取过期时间
const expiration = auth.getJWTExpiration();
if (expiration) {
console.log('JWT过期时间:', new Date(expiration * 1000));
}
```
## JWT载荷结构
```typescript
{
// 标准字段
sub: string; // 用户唯一标识(来自IDaaS)
iss: string; // 发行者: 'docreview-system'
aud: string; // 受众: 'docreview-frontend'
iat: number; // 签发时间
exp: number; // 过期时间
// 自定义用户信息字段
user_id: string; // 数据库中的用户ID
username: string; // 用户名
nick_name: string; // 用户昵称
email?: string; // 邮箱
phone_number?: string; // 手机号
ou_id: string; // 组织单位ID
ou_name: string; // 组织单位名称
is_leader: boolean; // 是否为负责人
user_role: string; // 用户角色
}
```
## 安全特性
1. **过期时间控制**: JWT过期时间设置为OAuth Token过期时间的90%,确保JWT在OAuth Token之前过期
2. **自动刷新**: 当OAuth Token刷新时,自动重新生成JWT
3. **签名验证**: 使用HS256算法和固定密钥进行签名验证
4. **过期检查**: 提供5分钟缓冲时间的过期预警
## 调试工具
使用 `AuthDebugInfo` 组件在开发阶段查看JWT状态:
```typescript
import { AuthDebugInfo } from '~/components/auth/AuthDebugInfo';
export default function DebugPage() {
return (
<div>
<h1></h1>
<AuthDebugInfo />
</div>
);
}
```
## 配置说明
### JWT密钥配置
`app/utils/jwt.ts` 中修改JWT密钥:
```typescript
// 生产环境中应该从环境变量读取
const JWT_SECRET = 'your-super-secret-jwt-key-change-this-in-production-2024';
```
### JWT配置参数
```typescript
const JWT_CONFIG = {
algorithm: 'HS256',
issuer: 'docreview-system',
audience: 'docreview-frontend'
};
```
## 注意事项
1. **生产环境安全**:
- JWT密钥应该从环境变量读取
- 删除或隐藏 `AuthDebugInfo` 组件
- 考虑使用更强的签名算法
2. **性能优化**:
- JWT验证在前端进行,减少服务器压力
- 使用session存储避免频繁重新生成
3. **错误处理**:
- JWT验证失败时应该引导用户重新登录
- 过期检查应该在关键操作前进行
## 工作流程
1. 用户通过OAuth2.0登录
2. `callback.tsx` 接收认证结果并保存用户信息到数据库
3. 根据保存的用户信息生成JWT
4. JWT存储在session中
5. 后续请求通过 `getUserSession` 检查JWT状态
6. 前端通过 `useAuth` hook 使用认证信息
7. 当OAuth Token刷新时,自动重新生成JWT
## 扩展功能
可以考虑的扩展功能:
- JWT黑名单机制
- 多设备登录管理
- 权限细粒度控制
- JWT刷新接口
- 客户端JWT存储(LocalStorage/SessionStorage