@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 => {
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 => {
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 => {
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,
});
routes.forEach(route => router.addRoute(route));
3. Token 解析工具
import { getToken, getCookies, parseToken, parseTokenJSON, base64Decode } from '@deppon/deppon-auth';
const tgc = getToken('TGC');
console.log(tgc);
const cookies = getCookies(['TGC', '_TOKENUUMS', 'U']);
console.log(cookies.TGC);
const userInfo = parseToken(cookies._TOKENUUMS);
console.log(userInfo);
const userInfoJSON = parseTokenJSON(cookies._TOKENUUMS);
console.log(userInfoJSON);
const decoded = base64Decode('SGVsbG8gV29ybGQ=');
console.log(decoded);
API 文档
createAuthGuard(options)
创建登录守卫函数,返回的守卫函数可直接用于 createDepponRouter 的 guards.beforeEach。
参数
options.cookieKeys (string[]) - 需要检测的 Cookie 键名数组
options.checkLogin (Function) - 登录状态检查函数,接收 cookies 对象,返回 boolean
options.onRequireLogin (Function) - 未登录时的处理函数,可以是同步或异步
options.showProgress (boolean, 可选) - 是否显示进度条,默认 false
options.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) - 登录守卫配置选项
将菜单树转换为路由配置。
参数
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 值。
参数
返回
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;
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(推荐)
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.setItem('userInfo', JSON.stringify(userInfo));
}
},
whiteList: ['/login', '/404', '/500'],
}),
},
});
app.use(router);
app.mount('#app');
直接使用 Vue Router
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.setItem('userInfo', JSON.stringify(userInfo));
}
},
whiteList: ['/login', '/404', '/500'],
},
});
app.use(router);
app.mount('#app');
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');
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