@deppon/deppon-auth
v2.2.1
Published
Login and permission management package
Maintainers
Readme
@deppon/deppon-auth
登录与权限管理包,提供登录守卫和路由解析功能。
功能特性
- ✅ 登录守卫(AuthGuard):基于 Cookie 的登录状态检测和路由守卫
- ✅ 路由解析器(RouteResolver):将菜单树转换为 Vue Router 路由配置
- ✅ Token 解析工具:提供 Cookie 读取和 Base64 解码工具函数
- ✅ TypeScript 支持:完整的类型定义
- ✅ 轻量级:只包含核心逻辑,不包含业务状态管理
安装
npm install @deppon/deppon-auth使用方式
1. 登录守卫(AuthGuard)
方式一:与 @deppon/deppon-router 集成(推荐)
如果使用 @deppon/deppon-router 创建路由,可以直接在 createDepponRouter 的 guards.beforeEach 中使用:
import { createApp } from 'vue';
import { createDepponRouter } from '@deppon/deppon-router';
import { createAuthGuard } from '@deppon/deppon-auth';
import routes from './routes';
const app = createApp(App);
// 创建路由并集成登录守卫
const router = createDepponRouter({
routes,
guards: {
beforeEach: createAuthGuard({
cookieKeys: ['TGC', '_TOKENUUMS', 'U'],
checkLogin: cookies => {
// 检查登录状态:存在 TGC 和 _TOKENUUMS 视为已登录
return !!(cookies.TGC && cookies._TOKENUUMS);
},
onRequireLogin: () => {
// 未登录时跳转到登录页
window.location.href = BASE_API + 'login/login.action';
},
whiteList: ['/login', '/404'], // 可选:白名单路由
onLoggedIn: async cookies => {
// 可选:登录后的回调,可以在这里处理用户信息
console.log('用户已登录', cookies);
},
}),
},
});
app.use(router);
app.mount('#app');方式二:直接为 Router 实例注册(兼容旧用法)
如果直接使用 Vue Router,可以使用 setupAuthGuard:
import { createApp } from 'vue';
import { createRouter } from 'vue-router';
import { setupAuthGuard } from '@deppon/deppon-auth';
import router from './router';
const app = createApp(App);
// 初始化登录守卫
setupAuthGuard({
router,
guardOptions: {
cookieKeys: ['TGC', '_TOKENUUMS', 'U'],
checkLogin: cookies => {
// 检查登录状态:存在 TGC 和 _TOKENUUMS 视为已登录
return !!(cookies.TGC && cookies._TOKENUUMS);
},
onRequireLogin: () => {
// 未登录时跳转到登录页
window.location.href = BASE_API + 'login/login.action';
},
whiteList: ['/login', '/404'], // 可选:白名单路由
onLoggedIn: async cookies => {
// 可选:登录后的回调,可以在这里处理用户信息
console.log('用户已登录', cookies);
},
},
});
app.use(router);
app.mount('#app');使用进度条(可选)
如果需要使用进度条,需要安装 nprogress 并传入进度条实例:
import NProgress from 'nprogress';
import 'nprogress/nprogress.css';
import { createDepponRouter } from '@deppon/deppon-router';
import { createAuthGuard } from '@deppon/deppon-auth';
const router = createDepponRouter({
routes,
guards: {
beforeEach: createAuthGuard({
cookieKeys: ['TGC', '_TOKENUUMS'],
checkLogin: cookies => !!(cookies.TGC && cookies._TOKENUUMS),
onRequireLogin: () => {
window.location.href = BASE_API + 'login/login.action';
},
showProgress: true,
progressBar: {
start: () => NProgress.start(),
done: () => NProgress.done(),
},
}),
},
});2. 路由解析器(RouteResolver)
将菜单树转换为路由配置:
import { resolveRoutes } from '@deppon/deppon-auth';
import { RouteRecordRaw } from 'vue-router';
import router from './router';
// 从接口获取菜单树
const menuTree = await getMenu();
// 转换为路由配置
const routes = resolveRoutes(menuTree, {
componentResolver: path => {
// 根据环境动态加载组件
// 例如:path = 'user/list' -> import('@/views/user/list.vue')
return () => import(`@/views/${path}.vue`);
},
metaTransformer: node => ({
title: node.name,
icon: node.icon,
// 其他元信息
}),
pathTransformer: node => node.path || `/${node.id}`,
nameTransformer: node => node.name || node.id,
skipNoComponent: true, // 跳过没有 component 的节点
});
// 添加到路由
routes.forEach(route => router.addRoute(route));3. Token 解析工具
import { getToken, getCookies, parseToken, parseTokenJSON, base64Decode } from '@deppon/deppon-auth';
// 读取单个 Cookie
const tgc = getToken('TGC');
console.log(tgc); // TGC 的值,不存在返回 false
// 批量读取 Cookie
const cookies = getCookies(['TGC', '_TOKENUUMS', 'U']);
console.log(cookies.TGC); // TGC 的值
// 解析 Token(标准格式:Base64 编码的逗号分隔字符串)
// 格式:1,userName,userCode,deptCode,deptName
const userInfo = parseToken(cookies._TOKENUUMS);
console.log(userInfo); // { userName, userCode, deptCode, deptName }
// 解析 Token(JSON 格式,兼容其他格式)
const userInfoJSON = parseTokenJSON(cookies._TOKENUUMS);
console.log(userInfoJSON); // 解析后的用户信息对象
// Base64 解码
const decoded = base64Decode('SGVsbG8gV29ybGQ=');
console.log(decoded); // 'Hello World'API 文档
createAuthGuard(options)
创建登录守卫函数,返回的守卫函数可直接用于 createDepponRouter 的 guards.beforeEach。
参数
options.cookieKeys(string[]) - 需要检测的 Cookie 键名数组options.checkLogin(Function) - 登录状态检查函数,接收 cookies 对象,返回 booleanoptions.onRequireLogin(Function) - 未登录时的处理函数,可以是同步或异步options.showProgress(boolean, 可选) - 是否显示进度条,默认 falseoptions.progressBar(ProgressBar, 可选) - 进度条实例,需要实现 start() 和 done() 方法options.whiteList(string[], 可选) - 白名单路由路径数组,默认 []options.onLoggedIn(Function, 可选) - 登录后的回调函数,接收 cookies 对象
返回
Function - 守卫函数,可直接用于 createDepponRouter 的 guards.beforeEach
setupAuthGuard(options)
直接为 Router 实例注册登录守卫(兼容旧用法)。
参数
options.router(Router) - Vue Router 实例options.guardOptions(AuthGuardOptions) - 登录守卫配置选项
resolveRoutes(menuTree, options)
将菜单树转换为路由配置。
参数
menuTree(MenuNode[]) - 菜单树数组options.componentResolver(Function) - 组件路径解析函数,接收 componentPath,返回组件options.metaTransformer(Function, 可选) - 路由元信息转换函数,接收 MenuNode,返回元信息对象options.pathTransformer(Function, 可选) - 路由路径转换函数,接收 MenuNode,返回路径字符串options.nameTransformer(Function, 可选) - 路由名称转换函数,接收 MenuNode,返回名称字符串options.skipNoComponent(boolean, 可选) - 是否跳过没有 component 的节点,默认 false
返回
RouteRecordRaw[] - 路由配置数组
getCookies(keys)
读取指定的 Cookie。
参数
keys(string[]) - Cookie 键名数组
返回
Record<string, string> - Cookie 键值对对象
getToken(key)
获取单个 Cookie 值。
参数
key(string) - Cookie 键名
返回
string | false - Cookie 值,不存在返回 false
parseToken(token)
解析 Token 中的用户信息(标准格式:Base64 编码的逗号分隔字符串)。
参数
token(string) - Token 字符串(格式:1,userName,userCode,deptCode,deptName)
返回
Record<string, string> | null - 解析后的用户信息对象 { userName, userCode, deptCode, deptName },解析失败返回 null
parseTokenJSON(token)
解析 Token 中的用户信息(JSON 格式,兼容其他格式)。
参数
token(string) - Token 字符串(Base64 编码的 JSON)
返回
Record<string, any> | null - 解析后的用户信息对象,解析失败返回 null
base64Decode(str)
Base64 解码。
参数
str(string) - Base64 编码的字符串
返回
string - 解码后的字符串
类型定义
// 菜单节点(标准格式)
interface MenuNode {
id: string;
text?: string; // 菜单文本/名称
name?: string; // 菜单名称(兼容字段)
uri?: string; // 路由路径/URI
path?: string; // 路由路径(兼容字段)
iconCls?: string; // 图标类名
leaf?: boolean; // 是否为叶子节点
component?: string; // 组件路径(用于动态导入)
children?: MenuNode[];
hidden?: boolean; // 是否隐藏
[key: string]: any;
}
// 登录守卫选项
interface AuthGuardOptions {
router: Router;
cookieKeys: string[];
checkLogin: (cookies: Record<string, string>) => boolean;
onRequireLogin: () => void | Promise<void>;
showProgress?: boolean;
progressBar?: ProgressBar;
whiteList?: string[];
onLoggedIn?: (cookies: Record<string, string>) => void | Promise<void>;
}
// 路由解析器选项
interface RouteResolverOptions {
componentResolver: (componentPath: string) => any;
metaTransformer?: (menuNode: MenuNode) => Record<string, any>;
pathTransformer?: (menuNode: MenuNode) => string;
nameTransformer?: (menuNode: MenuNode) => string;
skipNoComponent?: boolean;
}完整示例
使用 @deppon/deppon-router(推荐)
// main.ts
import { createApp } from 'vue';
import { createDepponRouter } from '@deppon/deppon-router';
import { createAuthGuard, parseToken } from '@deppon/deppon-auth';
import routes from './routes';
const app = createApp(App);
// 创建路由并集成登录守卫
const router = createDepponRouter({
routes,
guards: {
beforeEach: createAuthGuard({
cookieKeys: ['TGC', '_TOKENUUMS', 'U'],
checkLogin: cookies => {
return !!(cookies.TGC && cookies._TOKENUUMS);
},
onRequireLogin: () => {
window.location.href = BASE_API + 'login/login.action';
},
onLoggedIn: async cookies => {
// 解析用户信息并存储
const userInfo = parseToken(cookies._TOKENUUMS);
if (userInfo) {
// 存储到 localStorage 或 Vuex/Pinia
localStorage.setItem('userInfo', JSON.stringify(userInfo));
}
},
whiteList: ['/login', '/404', '/500'],
}),
},
});
app.use(router);
app.mount('#app');直接使用 Vue Router
// main.ts
import { createApp } from 'vue';
import { createRouter } from 'vue-router';
import { setupAuthGuard, parseToken } from '@deppon/deppon-auth';
import router from './router';
const app = createApp(App);
// 初始化登录守卫
setupAuthGuard({
router,
guardOptions: {
cookieKeys: ['TGC', '_TOKENUUMS', 'U'],
checkLogin: cookies => {
return !!(cookies.TGC && cookies._TOKENUUMS);
},
onRequireLogin: () => {
window.location.href = BASE_API + 'login/login.action';
},
onLoggedIn: async cookies => {
// 解析用户信息并存储
const userInfo = parseToken(cookies._TOKENUUMS);
if (userInfo) {
// 存储到 localStorage 或 Vuex/Pinia
localStorage.setItem('userInfo', JSON.stringify(userInfo));
}
},
whiteList: ['/login', '/404', '/500'],
},
});
app.use(router);
app.mount('#app');// main.ts
import { createApp } from 'vue';
import { createDepponRouter } from '@deppon/deppon-router';
import { createAuthGuard, resolveRoutes, getToken, parseToken } from '@deppon/deppon-auth';
import { getMenu } from './api/login';
import routes from './routes';
const app = createApp(App);
// 创建路由并集成登录守卫
const router = createDepponRouter({
routes,
guards: {
beforeEach: createAuthGuard({
cookieKeys: ['TGC', '_TOKENUUMS', 'U'],
checkLogin: cookies => {
return !!(cookies.TGC && cookies._TOKENUUMS);
},
onRequireLogin: () => {
window.location.href = BASE_API + 'login/login.action';
},
onLoggedIn: async cookies => {
// 解析用户信息并存储
const userInfo = parseToken(cookies._TOKENUUMS);
if (userInfo) {
localStorage.setItem('userInfo', JSON.stringify(userInfo));
}
},
whiteList: ['/login', '/404', '/500'],
showProgress: true,
progressBar: {
start: () => NProgress.start(),
done: () => NProgress.done(),
},
}).beforeEach,
afterEach: createAuthGuard({
cookieKeys: ['TGC', '_TOKENUUMS'],
checkLogin: () => true,
onRequireLogin: () => {},
showProgress: true,
progressBar: {
start: () => NProgress.start(),
done: () => NProgress.done(),
},
}).afterEach,
},
});
app.use(router);
// 在应用创建后初始化动态路由
app.mount('#app');
// 初始化动态路由(在 Vue 实例创建后执行)
async function initRoutes() {
// 检查是否已登录
const tgc = getToken('TGC');
const tokenNums = getToken('_TOKENUUMS');
if (tgc && tokenNums) {
try {
// 从接口获取菜单树
const result = await getMenu('0');
const menuTree = result.data.nodes || [];
// 转换为路由配置
const dynamicRoutes = resolveRoutes(menuTree, {
componentResolver: path => {
// 动态加载组件
return () => import(`@/views/${path}.vue`);
},
metaTransformer: node => ({
title: node.text || node.name,
icon: node.iconCls || node.icon,
hidden: node.hidden === false ? false : node.hidden || false,
}),
pathTransformer: node => {
return node.uri === null ? '' : node.uri || node.path || `/${node.id}`;
},
nameTransformer: node => node.text || node.name || node.id,
skipNoComponent: true,
});
// 添加到路由
dynamicRoutes.forEach(route => router.addRoute(route));
} catch (error) {
console.error('[deppon-auth] 路由初始化失败:', error);
}
}
}
// 执行路由初始化
initRoutes();注意:initRoutes() 应该在应用挂载后执行,通常在 main.ts 中直接调用,或者在 Vue 实例的 created 生命周期中调用。
依赖说明
dependencies
@deppon/deppon-router@^1.15.8- Vue Router 封装包(推荐使用)@babel/runtime@^7.17.7- Babel 运行时
peerDependencies
vue@^3.0.0- Vue 3 框架vue-router@^4.0.0- Vue Router 4
注意事项
- 登录状态检查:
checkLogin函数需要根据实际业务逻辑实现,本包只提供框架 - 组件路径解析:
componentResolver需要根据项目的组件路径规则实现 - 进度条:如果需要使用进度条,需要自行安装
nprogress或其他进度条库 - 用户信息管理:本包不包含用户信息的状态管理,需要在业务项目中自行处理
License
MIT
