Files
leaudit-platform-frontend/docs/JWT_IMPLEMENTATION.md
T

5.0 KiB
Raw Blame History

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中返回认证信息

// 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
  });
}

在组件中使用认证信息

// 在你的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验证和状态检查

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载荷结构

{
  // 标准字段
  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状态:

import { AuthDebugInfo } from '~/components/auth/AuthDebugInfo';

export default function DebugPage() {
  return (
    <div>
      <h1>认证调试页面</h1>
      <AuthDebugInfo />
    </div>
  );
}

配置说明

JWT密钥配置

app/utils/jwt.ts 中修改JWT密钥:

// 生产环境中应该从环境变量读取
const JWT_SECRET = 'your-super-secret-jwt-key-change-this-in-production-2024';

JWT配置参数

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