library-picturebook-activity/backend/docs/TENANT_LOGIN_GUIDE.md
2025-11-23 14:04:20 +08:00

227 lines
5.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 租户登录使用指南
## 概述
系统已完整支持多租户登录功能,每个租户可以独立访问系统,数据完全隔离。
## 租户识别方式
系统支持以下方式识别租户:
### 1. URL参数方式推荐
在登录页面URL中添加 `tenant` 参数:
```
http://your-domain.com/login?tenant=tenant-a
```
登录页面会自动识别租户编码,并在登录时自动发送。
### 2. 登录表单输入
如果URL中没有租户参数登录页面会显示租户编码输入框用户可以手动输入。
### 3. 请求头方式
前端会自动将租户信息添加到所有API请求的请求头中
- `X-Tenant-Code`: 租户编码
- `X-Tenant-Id`: 租户ID
## 使用流程
### 方式一通过URL参数访问推荐
1. **访问租户登录页面**
```
http://your-domain.com/login?tenant=tenant-a
```
2. **输入用户名和密码**
- 用户名:租户内的用户名
- 密码:用户密码
- 租户编码已自动填充从URL参数
3. **登录成功**
- 系统自动保存租户信息到 localStorage
- 后续所有API请求都会自动携带租户信息
- 用户只能看到和操作自己租户的数据
### 方式二:手动输入租户编码
1. **访问登录页面**
```
http://your-domain.com/login
```
2. **输入租户信息**
- 租户编码:输入租户编码(如:`tenant-a`
- 用户名:租户内的用户名
- 密码:用户密码
3. **登录成功**
- 系统保存租户信息
- 后续请求自动携带租户信息
## 后端API使用
### 登录接口
**请求:**
```bash
POST /api/auth/login
Content-Type: application/json
{
"username": "user1",
"password": "password123",
"tenantCode": "tenant-a" // 可选,也可以从请求头获取
}
```
**或者通过请求头:**
```bash
POST /api/auth/login
X-Tenant-Code: tenant-a
Content-Type: application/json
{
"username": "user1",
"password": "password123"
}
```
**响应:**
```json
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": {
"id": 1,
"username": "user1",
"nickname": "用户1",
"email": "user1@example.com",
"tenantId": 2,
"tenantCode": "tenant-a",
"roles": ["admin"],
"permissions": ["user:read", "user:create", ...]
}
}
```
### 其他API请求
登录后所有API请求都会自动携带租户信息通过JWT Token或请求头后端会自动过滤数据
```bash
GET /api/users
Authorization: Bearer <token>
X-Tenant-Code: tenant-a # 自动添加
```
返回的数据只会包含该租户的用户。
## 前端实现细节
### 1. 登录页面自动识别租户
登录页面 (`Login.vue`) 会:
- 从URL参数 `?tenant=xxx` 获取租户编码
- 如果URL中没有从 localStorage 读取之前保存的租户编码
- 如果都没有,显示租户输入框
### 2. 请求拦截器自动添加租户信息
所有API请求都会自动添加租户信息到请求头
```typescript
// utils/request.ts
service.interceptors.request.use((config) => {
const tenantCode = getTenantCode();
const tenantId = getTenantId();
if (tenantCode) {
config.headers['X-Tenant-Code'] = tenantCode;
}
if (tenantId) {
config.headers['X-Tenant-Id'] = tenantId;
}
return config;
});
```
### 3. 登录后保存租户信息
登录成功后,系统会自动保存:
- Token
- 租户编码 (tenantCode)
- 租户ID (tenantId)
这些信息保存在 localStorage 中,页面刷新后仍然有效。
## 示例场景
### 场景1租户A的用户登录
1. 访问:`http://your-domain.com/login?tenant=tenant-a`
2. 输入用户名和密码
3. 登录后只能看到租户A的数据
### 场景2租户B的用户登录
1. 访问:`http://your-domain.com/login?tenant=tenant-b`
2. 输入用户名和密码
3. 登录后只能看到租户B的数据
4. 租户A的数据完全不可见
### 场景3超级租户管理员登录
1. 访问:`http://your-domain.com/login?tenant=super`
2. 使用超级管理员账号登录
3. 可以管理所有租户
## 注意事项
1. **租户编码必须唯一**每个租户都有唯一的编码code
2. **用户属于特定租户**:用户只能登录到自己所属的租户
3. **数据完全隔离**:不同租户的数据完全隔离,无法互相访问
4. **租户信息持久化**:登录后租户信息保存在 localStorage刷新页面不会丢失
5. **切换租户**:如果需要切换租户,需要先登出,然后使用新的租户编码登录
## 故障排查
### 问题1登录时提示"无法确定租户信息"
**原因**没有提供租户编码或租户ID
**解决**
- 在URL中添加 `?tenant=xxx` 参数
- 或者在登录表单中输入租户编码
- 或者通过请求头 `X-Tenant-Code` 提供
### 问题2登录时提示"用户不属于该租户"
**原因**:用户不属于指定的租户
**解决**
- 确认租户编码是否正确
- 确认用户是否属于该租户
- 联系管理员检查用户和租户的关联关系
### 问题3登录后看不到数据
**原因**:可能是租户信息没有正确传递
**解决**
- 检查浏览器控制台的网络请求,确认请求头中是否包含 `X-Tenant-Code`
- 检查 localStorage 中是否保存了租户信息
- 确认后端是否正确识别了租户
## 开发建议
1. **使用URL参数方式**:这是最用户友好的方式,用户只需要记住租户的访问链接
2. **提供租户选择器**:如果系统需要支持租户切换,可以在前端添加租户选择器
3. **错误提示优化**:当租户信息缺失时,提供清晰的错误提示
4. **租户信息显示**:在用户界面显示当前租户信息,让用户知道自己在哪个租户下操作