5.0 KiB
5.0 KiB
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; // 用户角色
}
安全特性
- 过期时间控制: JWT过期时间设置为OAuth Token过期时间的90%,确保JWT在OAuth Token之前过期
- 自动刷新: 当OAuth Token刷新时,自动重新生成JWT
- 签名验证: 使用HS256算法和固定密钥进行签名验证
- 过期检查: 提供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'
};
注意事项
-
生产环境安全:
- JWT密钥应该从环境变量读取
- 删除或隐藏
AuthDebugInfo组件 - 考虑使用更强的签名算法
-
性能优化:
- JWT验证在前端进行,减少服务器压力
- 使用session存储避免频繁重新生成
-
错误处理:
- JWT验证失败时应该引导用户重新登录
- 过期检查应该在关键操作前进行
工作流程
- 用户通过OAuth2.0登录
callback.tsx接收认证结果并保存用户信息到数据库- 根据保存的用户信息生成JWT
- JWT存储在session中
- 后续请求通过
getUserSession检查JWT状态 - 前端通过
useAuthhook 使用认证信息 - 当OAuth Token刷新时,自动重新生成JWT
扩展功能
可以考虑的扩展功能:
- JWT黑名单机制
- 多设备登录管理
- 权限细粒度控制
- JWT刷新接口
- 客户端JWT存储(LocalStorage/SessionStorage)