Files
leaudit-platform-frontend/app/hooks/useAuth.ts
T

134 lines
2.9 KiB
TypeScript

/**
* 认证相关的React Hook
* 提供JWT认证状态管理和用户信息获取功能
*/
import { useLoaderData } from "@remix-run/react";
import { JWTUtils, type UserInfoForJWT } from "~/utils/jwt";
// 定义从loader返回的认证数据结构
interface AuthLoaderData {
userInfo?: {
sub: string;
user_id: string;
username: string;
nick_name: string;
email?: string;
phone_number?: string;
ou_id: string;
ou_name: string;
is_leader: boolean;
user_role: string;
frontend_jwt?: string;
};
isAuthenticated?: boolean;
userRole?: string;
}
/**
* 认证状态Hook
* @returns 认证状态和用户信息
*/
export function useAuth() {
// 从loader data中获取认证信息
const loaderData = useLoaderData() as AuthLoaderData;
const isAuthenticated = loaderData?.isAuthenticated || false;
const userInfo = loaderData?.userInfo;
const frontendJWT = userInfo?.frontend_jwt;
/**
* 验证JWT是否有效
* @returns JWT验证结果
*/
const validateJWT = () => {
if (!frontendJWT) {
return { valid: false, error: "JWT不存在" };
}
return JWTUtils.verifyJWT(frontendJWT);
};
/**
* 检查JWT是否即将过期
* @param bufferMinutes 缓冲时间(分钟)
* @returns 是否即将过期
*/
const isJWTExpiringSoon = (bufferMinutes: number = 5) => {
if (!frontendJWT) {
return true;
}
return JWTUtils.isJWTExpiringSoon(frontendJWT, bufferMinutes);
};
/**
* 从JWT中获取用户信息
* @returns 用户信息
*/
const getUserInfoFromJWT = (): UserInfoForJWT | null => {
if (!frontendJWT) {
return null;
}
return JWTUtils.extractUserInfo(frontendJWT);
};
/**
* 获取JWT过期时间
* @returns 过期时间戳
*/
const getJWTExpiration = () => {
if (!frontendJWT) {
return null;
}
return JWTUtils.getJWTExpiration(frontendJWT);
};
/**
* 检查用户是否有特定角色
* @param role 角色名称
* @returns 是否有该角色
*/
const hasRole = (role: string) => {
return userInfo?.user_role === role;
};
/**
* 检查用户是否为管理员
* @returns 是否为管理员
*/
const isAdmin = () => {
return userInfo?.user_role === 'developer' || userInfo?.is_leader === true;
};
return {
// 基本认证状态
isAuthenticated,
userInfo,
frontendJWT,
// JWT相关方法
validateJWT,
isJWTExpiringSoon,
getUserInfoFromJWT,
getJWTExpiration,
// 权限检查方法
hasRole,
isAdmin,
// 便捷属性
userId: userInfo?.user_id,
username: userInfo?.username,
nickName: userInfo?.nick_name,
email: userInfo?.email,
phoneNumber: userInfo?.phone_number,
ouName: userInfo?.ou_name,
userRole: userInfo?.user_role,
isLeader: userInfo?.is_leader
};
}
export default useAuth;