Files
medical-mall/doc_mall/consumer/MULTI_ROLE_LOGIN_ARCHITECTURE.md

101 lines
3.2 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.
# 多端、多角色登录架构设计与权限控制方案 (RFC)
## 1. 业务背景
本项目包含多个业务线(如:商城、学校管理、配送中心等)及多种用户角色(如:消费者、学生、教师、配送员等)。为减少重复开发并保持用户体验一致,各端统一共用一套登录模板。
当前面临挑战:
1. **角色误判**:新用户注册后被分配了错误的角色(如:注册商城用户却分配了学生角色)。
2. **越权访问**RLS 策略未对角色进行细分,导致特定操作在特定角色下报 403 权限错误。
3. **分流逻辑耦合**:登录成功后的跳转逻辑分散在各页面,难以维护。
---
## 2. 架构设计核心:解耦登录与业务角色
### 2.1 统一身份中心 (Auth)
- 依然使用 Supabase Auth 作为认证源。
- 登录仅负责:验证凭证 -> 获取 JWT -> 建立 Session。
### 2.2 业务配置化分流
`utils/store.uts` 或专门的导航服务中维护角色首页映射表。
```typescript
// 路由分流映射配置
export const ROLE_HOME_PAGES = {
'admin': '/pages/mall/admin/index',
'consumer': '/pages/mall/consumer/index',
'teacher': '/pages/school/teacher/index',
'student': '/pages/school/student/index',
'delivery': '/pages/mall/delivery/index'
}
/**
* 根据角色执行自动导航
*/
export function navigateToRoleHome(role: string) {
const target = ROLE_HOME_PAGES[role] || '/pages/mall/consumer/index';
uni.reLaunch({ url: target });
}
```
---
## 3. 注册阶段的角色控制
### 3.1 显式角色声明
注册时,根据当前所属的应用端,向 `ensureUserProfile` 传递预期的 `defaultRole`
- **商城端注册**:默认传 `consumer`
- **学校端注册**:默认传 `student`
### 3.2 修补逻辑建议 (utils/sapi.uts)
`insert``ak_users` 表时,必须显式包含 `role` 字段。
```typescript
const newUserData = new UTSJSONObject()
newUserData.set('id', userId)
newUserData.set('email', email)
newUserData.set('role', finalRole) // 显式写入业务角色
```
---
## 4. 数据库 RLS 策略完善 (SQL 示例)
### 4.1 用户资料表 (ak_users)
确保用户只能更新自己的资料,但不能绕过逻辑修改自己的 `role`
```sql
-- 开启 RLS
ALTER TABLE ak_users ENABLE ROW LEVEL SECURITY;
-- 允许用户查看自己的资料
CREATE POLICY "Users can view own data" ON ak_users
FOR SELECT TO authenticated
USING (auth.uid() = id);
```
### 4.2 业务表角色锁 (以 ml_shopping_cart 为例)
只有角色为 `consumer` 的用户才能执行购物车操作。
```sql
-- 只有消费者可以插入购物车
CREATE POLICY "Only consumers can use cart"
ON ml_shopping_cart
FOR INSERT TO authenticated
WITH CHECK (
auth.uid() = user_id AND
EXISTS (
SELECT 1 FROM ak_users
WHERE id = auth.uid() AND role = 'consumer'
)
);
```
---
## 5. 迁移与修复建议
1. **现状修正**:检查 Supabase 后台 `ak_users` 表,手动或批量修改 `student` 角色的消费者用户为 `consumer`
2. **清理缓存**:小程序环境下需清理本地 `user_id` 缓存后重新登录,以刷新受限角色。
3. **URL 规范**:建议将各端的页面放入对应的分层目录中(如 `/pages/mall/...`, `/pages/school/...`),便于权限隔离。