请求与认证

XYGo Admin 2026-04-01 29 次阅读

tenantRequest 封装、API 命名空间与 JWT 鉴权机制

请求与认证

API 命名空间

租户端与平台端使用不同的 API 命名空间,互不干扰:

请求实例 URL 前缀 Token 方式 项目
adminRequest /admin Bearer Token(平台管理员) web
memberRequest /member Xy-User-Token(前台会员) web
siteRequest /site web / web-tenant
adminRequest(租户版) /tenant Bearer Token(租户管理员) web-tenant

租户前端中的 adminRequest 实际前缀为 /tenant(在 utils/http/index.ts 中配置),请求形如:

复制代码
POST /tenant/auth/login
GET  /tenant/menu/routes
GET  /tenant/user/list

请求封装

租户端的 HTTP 封装位于 src/utils/http/,与主项目结构一致,但有以下差异:

1. 无 member 用户态

拦截器中不使用 useMemberStore,不注入 Xy-User-Token。租户端是纯管理后台,不处理前台会员登录状态。

2. 统一 Bearer Token

所有 /tenant/* 请求通过请求拦截器自动注入:

复制代码
Authorization: Bearer <token>

Token 存储在 useUserStore 中,由 Pinia 持久化插件自动保存到 localStorage。

3. baseURL 配置

typescript 复制代码
const { VITE_API_URL } = import.meta.env

const axiosInstance = axios.create({
  timeout: 15000,
  baseURL: VITE_API_URL  // 开发环境: "/"  生产环境: "https://xxx.com"
})

站点信息接口

src/api/site.ts 用于获取站点基本信息(名称、Logo、主题等),使用公开的 /site/index 接口,无需 Token:

typescript 复制代码
import { siteRequest } from '@/utils/http'

export function fetchSiteIndex() {
  return siteRequest.get<SiteInfo>({ url: '/index' })
}

注意site.ts 必须使用 siteRequest(带 /site 前缀),不能用裸 axios.get('/site/index'),否则生产环境中 baseURL 不会生效,请求会发到前端域名而非后端。

响应处理

响应拦截器的业务码处理与主项目一致:

业务码 含义 处理
0 成功 返回 data 字段
-1 业务错误 ElMessage 提示
61 未授权 清除 Token,跳转登录页(3 秒防抖)
10010 被踢下线 弹窗提示

登录流程

复制代码
用户访问 /tenant/login
  → 输入账号密码
    → POST /tenant/auth/login
      → 后端校验 xy_tenant_admin + 租户状态
        → 签发租户 JWT(含 TenantId + AdminId)
          → 前端存储 Token 到 useUserStore
            → 获取菜单 GET /tenant/menu/routes
              → 动态注册路由
                → 跳转到 /tenant/dashboard

请求示例

typescript 复制代码
// api/backend/system/user.ts
import { adminRequest } from '@/utils/http'

export function fetchUserList(params: any) {
  return adminRequest.get({ url: '/user/list', params })
  // 实际请求: GET /tenant/user/list
}

export function fetchSaveUser(data: any) {
  return adminRequest.post({ url: '/user/edit', params: data })
  // 实际请求: POST /tenant/user/edit
}