4、用户管理模块:注册登录、角色权限、企业信息管理、多租户设计

用户管理模块,说白了就是整个平台的「大门」和「门禁系统」。

我做过好几个聚合平台项目,每次都被问同一个问题:「用户来了怎么管?」

嗯,这个问题其实挺深的。你想想看,一个需求响应聚合平台,既要管普通用户,又要管企业用户,还得区分不同角色。搞不好,权限乱套了,数据就串了。

今天咱们就聊聊这个模块怎么搭。

4.1 注册与登录:第一道防线

注册登录这块,我个人习惯用「手机号+验证码」作为主登录方式。为什么?

因为需求响应平台涉及电费结算、补贴发放,必须实名。手机号实名制,天然就是最好的身份锚点。

核心流程:

  • 用户输入手机号 → 获取短信验证码
  • 验证码校验通过 → 创建账号(首次)或登录(已有账号)
  • 补充企业信息 → 完成实名认证

我在项目中遇到过一个问题:验证码被刷。有人写脚本疯狂请求,短信费一天烧掉几千块。

解决办法?加个图形验证码,或者限制同一手机号60秒内只能发一次。嗯,这些都是血泪教训。

// 伪代码:注册登录接口设计
POST /api/v1/auth/register
{
  "phone": "13800138000",
  "code": "123456",
  "password": "encrypted_string"
}

POST /api/v1/auth/login
{
  "phone": "13800138000",
  "password": "encrypted_string"
}

小技巧:密码不要明文存。用bcrypt或Argon2做哈希。我曾经见过有人用MD5存密码,结果数据库泄露,用户信息全完蛋。

4.2 角色权限:谁可以干什么

角色权限设计,我建议用「RBAC模型」——基于角色的访问控制。

说白了就是:你是什么角色,就有什么权限。角色和权限分开管理,灵活很多。

角色 权限范围 典型操作
超级管理员 全部 创建租户、全局配置、查看所有数据
企业管理员 本企业内 管理本企业用户、查看本企业报表
普通用户 个人 查看个人数据、参与需求响应
审核员 审核相关 审核企业资质、审核响应记录

为什么这样分?

你想想看,如果让普通用户看到其他企业的用电数据,那不乱套了?

我曾经帮一个客户排查问题,发现他们把所有用户都放在一个角色里,结果A企业的员工能看到B企业的补贴金额。嗯,这种事故一次就够了。

避坑指南:权限设计一定要「最小权限原则」。默认不给任何权限,需要什么加什么。我曾经见过一个平台,新注册用户默认是「管理员」角色,吓得我赶紧让他们改了。

4.3 企业信息管理:不只是填个表单

企业信息管理,看起来就是填个公司名、统一社会信用代码、法人信息。其实没那么简单。

我做过一个项目,企业信息提交后,需要人工审核。结果审核员每天要看好几百份资料,眼睛都看花了。

后来我们加了「OCR自动识别」——上传营业执照照片,自动提取信息。准确率90%以上,剩下的再人工复核。效率提升了好几倍。

// 企业信息数据结构示例
{
  "enterprise_id": "ENT20240001",
  "name": "某某能源科技有限公司",
  "credit_code": "91110108MA01XXXXXX",
  "legal_person": "张三",
  "contact_phone": "13800138000",
  "status": "pending", // pending, approved, rejected
  "created_at": "2024-01-15T10:30:00Z"
}

关键字段说明:

  • 企业状态:待审核、已通过、已驳回。驳回时要写明原因,方便用户修改后重新提交。
  • 资质文件:营业执照、电力业务许可证等。建议用对象存储(OSS)保存,别放数据库里。
  • 审核记录:谁审核的、什么时候审核的、审核意见是什么。方便追溯。

4.4 多租户设计:数据隔离的艺术

多租户,说白了就是「一套系统,给多个企业用」。但数据不能串。

我常用的方案有三种:

  1. 独立数据库:每个企业一个数据库。隔离性最好,但成本高。
  2. 共享数据库,独立Schema:每个企业一个Schema。隔离性中等,管理方便。
  3. 共享数据库,共享Schema:所有企业数据放一起,用tenant_id区分。成本最低,但隔离性最差。

我个人习惯用第三种方案,加一层「数据权限过滤」。

什么意思?就是每个SQL查询都自动带上 WHERE tenant_id = ?。这样开发的时候不用每个接口都手动加,省事很多。

// 多租户数据过滤示例(MyBatis拦截器思路)
@Interceptor
public class TenantInterceptor {
    public String intercept(String sql) {
        String tenantId = TenantContext.getCurrentTenantId();
        return sql + " AND tenant_id = '" + tenantId + "'";
    }
}

避坑指南:多租户最容易出问题的就是「忘记加tenant_id」。我曾经上线后才发现,某个报表接口没做租户隔离,结果A企业看到了B企业的数据。嗯,那个周末我是在机房度过的。

还有一个细节:租户的「套餐」管理。

不同企业可能买了不同的服务包。比如基础版只能管理100个用户,高级版可以管理1000个。这些限制要在用户管理模块里做校验。

小技巧:租户信息可以放在JWT Token里。用户登录后,每次请求都带上Token,后端解析出tenant_id。这样就不用每次查数据库了,性能好很多。

4.5 整体架构图

下面这张图,是我画的一个用户管理模块的核心逻辑。你看一眼就明白了。

用户管理模块核心架构 用户层 普通用户 | 企业管理员 | 超级管理员 | 审核员 认证层 手机号+验证码 | 密码登录 | JWT Token 权限层(RBAC) 角色管理 | 权限分配 | 数据权限过滤 数据层(多租户) tenant_id隔离 | 企业信息表 | 用户表 | 权限表

这张图从下往上看:

  • 最底层是数据层,用tenant_id做隔离
  • 往上是权限层,用RBAC控制谁能干什么
  • 再往上是认证层,确认你是谁
  • 最顶层是用户层,不同角色各司其职

嗯,这个架构我用了好几年,基本没出过大问题。

4.6 避坑总结

最后,我把这些年踩过的坑总结一下:

  • 验证码安全:加图形验证码,限制发送频率。别让脚本刷爆你的短信费。
  • 密码存储:别用MD5,用bcrypt。数据库泄露了还能扛一阵。
  • 权限最小化:默认不给权限,需要什么加什么。别图省事给个「管理员」了事。
  • 多租户隔离:每个SQL都带上tenant_id。最好用拦截器自动加,别靠人工记。
  • 审核流程:企业信息提交后要有审核机制。驳回时写清楚原因,别让用户猜。

用户管理模块,看起来简单,其实细节很多。但只要把「认证、权限、租户」这三件事理清楚,后面就顺了。


公众号:蓝海资料掘金营,微信deep3321