134 lines
2.9 KiB
TypeScript
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;
|