授权服务(@uniboot/auth)

与框架无关的 OAuth 2.0 登录状态机与路由权限守卫,将 登录 一文中的授权中心跳转、换票、路由拦截沉淀为可复用能力。账号资料、忘记密码等由 @uniboot/admin 负责。

能力导出说明
OAuth 状态机createOAuthAuthServicestate 防伪、code 换票、401 刷新
路由权限守卫setupAuthPermissionGuard未登录重定向、OAuth 回调、动态路由、白名单
登录 APIcreateAuthApi/auth/login/oauth/logout(本地表单场景)
页面组件AuthLoginPage本地登录表单(不走 SSO 整页跳转时用)

类型以 XxxLike 描述宿主 router / user,不直接依赖具体版本的 vue-routerpeerDependenciesvuevue-i18nuniboot-uidependencies@uniboot/request

Auth 模板接入

三服务地址均需配置(与 用户服务 一致):

环境变量含义鉴权侧用法
APP_PUBLIC_API_URL业务系统默认 request
APP_PUBLIC_AUTH_SERVICE_URL授权服务Bundle → authHttp;OAuth 换票 / 刷新
APP_PUBLIC_ADMIN_SERVICE_URL用户服务Bundle → adminHttp(见 admin 文档)

模板职责拆分:

文件职责
src/utils/request.tscreateUnibootAdminHttpBundle 创建 authHttp / adminHttp 与各 API
src/setup/auth-runtime.tsHTTP 公共配置、OAuth 实例、setupPermissionGuard、401 刷新(不含 admin 安装)
src/router/guard/permission.ts调用 setupPermissionGuard
src/install/plugins/uniboot-admin.ts直接调用 setupUnibootAdmin(见 用户服务
ts
// src/setup/auth-runtime.ts(节选)
oauthAuthService = createOAuthAuthService({
  authServiceUrl: config.authServiceUrl,
  appBase: config.appBase,
  redirectUri: config.redirectUri,
  clientId: config.clientId,
  http, // 与守卫共用;401 刷新也走同一实例
  tokenPath: '/oauth/token',
  refreshTokenPath: '/oauth/refresh_token',
})

setupAuthPermissionGuard({
  router,
  oauth: oauthAuthService,
  useAuthServiceLogin: Boolean(config.authServiceUrl?.trim()),
  user: createAuthPermissionUserBridge(),
  // loginPath / whiteList / dynamicRoutes / progress / feedback ...
})
ts
// src/router/guard/permission.ts
import { setupPermissionGuard } from '@/setup/auth-runtime'
import request from '@/utils/request'

export default function createPermissionGuard(router: Router) {
  setupPermissionGuard(router, request)
}

refreshHttpAccessToken(HTTP 401 拦截器)与守卫共用同一个 oauthAuthService,登录 / 刷新 / 路由拦截的 token 语义一致。须在 createRouter 之后、app.use(router) 之前注册守卫。

createOAuthAuthService

把「统一授权中心登录」拆成纯函数,中间状态默认写入 sessionStorage(可换 OAuthStorageLike)。

参数

名称说明类型默认值
authServiceUrl授权中心地址string
appBase应用基础路径,用于推导 redirectUristring
redirectUri回调地址;未传按 ${origin}${appBase} 推导stringappBase 推导
clientIdOAuth 客户端 IDstring'koms'
scope授权范围string'user_info'
http换票 / 刷新用的 HTTP 客户端object
tokenPath换票路径string'/oauth/token'
refreshTokenPath刷新路径string'/oauth/refresh_token'
state防伪校验值stringOAUTH_FIXED_STATE'STATE'
storage中间状态存储objectsessionStorage
getOrigin推导 redirectUri 时取源function() => location.origin

返回值

名称说明类型
buildAuthorizeHref生成授权中心 /login URL,并写入 statefunction
rememberReturnPath记忆登录前地址function
takeAndClearReturnPath取出并清除返回地址function
getLoginState读取已写入的 statefunction
exchangeAuthorizationCodecode{ accessToken, refreshToken? }function
refreshAccessTokenrefresh token 换新令牌对function
clearLoginSessionMarkers清理 state / 返回地址function

实现细节

  • 未显式传 state 时用固定值 'STATE':授权中心是整页跳转,SPA 无法跨跳转共享内存;固定值 + sessionStorage 足以满足同源 CSRF 防护。
  • 令牌解析兼容 access_token / accessToken、顶层或嵌套在 result / data、以及 JSON 字符串;响应含 error 时抛出 error_description

setupAuthPermissionGuard

组装 router.beforeEach:访问拦截 → 授权中心 → 回调换票 → 动态路由。

参数

名称说明类型默认值
router满足 AuthPermissionRouterLike 即可object
usertoken / 用户信息 / 路由表适配器object
dynamicRoutes首页路由、路由名、首个可用路由查找object
loginPath登录页路径string
indexPath首页路径string
error403Path无权限页路径string
whiteList免登录白名单array
titledocument.title 回退string / function
useAuthServiceLogin是否整页跳转授权中心booleanfalse
oauthcreateOAuthAuthService 实例object
tabs动态路由挂载后设置多标签路由名object
progress进度条钩子object
feedback错误提示object
redirectTo跳转授权中心functionwindow.location.href
isExternal外链判断,动态挂载时跳过function匹配 http(s): / mailto: / tel:

执行流程

  1. OAuth 回调(URL 带 code 且未登录):校验 error / state → 换票写 token → takeAndClearReturnPath 跳回。
  2. 白名单:放行;若目标是 loginPath 且启用了 useAuthServiceLogin,记忆 redirect 后跳转授权中心。
  3. 已登录:有用户信息则放行;否则 loadUserInfo → 挂动态路由 → next({ ...to, replace: true });失败则清登录态回登录页。
  4. 未登录且未启用 OAuth:跳转本地登录页并带 redirect
  5. 未登录且启用 OAuth:记忆地址后整页跳转授权中心,next(false)

createAuthApi

本地表单登录场景(Auth 模板默认走 SSO,通常不直接用)。

参数

名称说明类型默认值
httpHTTP 客户端object
paths部分覆盖 defaultAuthApiPathsobjectlogin: '/auth/login'logout: '/oauth/logout'

方法

名称说明类型
login默认 withToken: false;可用 login<T>() 指定返回类型function
logout登出function

useLoginAccount({ api })LoginPage 表单值映射为登录请求(trim 用户名并透传验证码)。

AuthLoginPage

不启用 useAuthServiceLogin、在前端渲染登录表单时使用。内部已接 useLoginAccount;写 token、跳转仍由宿主在 onFinish 中完成。Auth 模板默认 SSO,不引用该组件。

属性

名称说明类型默认值
apicreateAuthApi 实例object
logoLogo URLstring
illustration插画 URLstring
onFinish登录成功回调;resultapi.login 返回值function
showCaptcha是否展示验证码booleanfalse
getCaptcha获取验证码function
initialValues初始表单值object

事件 / 插槽

名称说明
language-change语言切换
#actions / #footer表单下方 / 左侧底部

i18n

mergeUnibootAuthLocales(i18n) 合并 authLocaleZhCn / authLocaleEnzh_CN/zh-CNen_US/en-US。命名空间为 unibootAuth.login.*。Auth 模板在 uniboot-admin 安装插件里与 admin 文案一并处理;账号域更多文案见 @uniboot/admin