首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >村民、村干部、管理员三类角色的统一身份认证:万村乐数字乡村的 Sa-Token 落地记录

村民、村干部、管理员三类角色的统一身份认证:万村乐数字乡村的 Sa-Token 落地记录

原创
作者头像
小小码农爱奋斗
发布2026-08-20 15:53:18
发布2026-08-20 15:53:18
1400
举报

一个村不是一个系统,是好几拨人共用一套数据

做万村乐数字乡村这类基层平台,身份这块比想象中麻烦。同一套数据,村民在小程序上看三务公开、发帖、逛一村一品商城;村干部在手机管理端帮老人录网格信息、审帖子、加减家庭积分;村管理员在村后台配菜单、开投票、发通知公告;镇县一级的人又要在政务管理端跨村看汇总。角色不同,入口不同,端也不同。

万村乐 Java 版的后端技术栈是 JDK 1.8、SpringBoot 2.5.4、MySQL 8.0.28、MybatisPlus 3.5.1,鉴权用的是 Sa-Token 1.30.0,前端 Vue 3.2.31 配 Ant-Design-Vue 3.2.10,前后端分离。小程序和 APP 那一层是 UNI-APP 打包出来的,等于同一套后端要同时面对 5 类客户端:微信小程序、公众号 H5、PC 浏览器、安卓 APP、iOS APP。把认证做成每端一套,后面维护会很难受,所以从一开始就按统一会话来设计。

账号、角色、区划这三样得拆开

早期版本容易犯的错,是把角色直接写进用户表的一个字段里。基层场景根本撑不住:一个人可能既是村民,又是村里的商家,还兼着村小组长。万村乐后台的做法是账号体系与角色体系分离,村管理员可以自行创建多个权限角色来控制不同账号看到不同内容,村民侧另有村民用户组,不同用户组可以在不同板块发帖。

落到表结构上,大致是这么四张:

village_id 这一列很关键。万村乐的地区管理支持后台自由添加全国各地村庄并分配管理者账号,可视化大数据那边的权限还要按省、市、县、镇、村五级划分,如果角色不带区划,跨村查询就没法收口。

Sa-Token 的配置:多端共存与并发登录

Sa-Token 1.30.0 在这个场景里比较省事的地方,是它把会话和权限校验都收在一层,不用为了小程序单独写一套拦截器。配置上要注意 token 风格和是否允许并发登录:

is-share 设成 false 是踩过坑之后改的。早期共享同一个 token,村干部在 PC 后台退出登录,手机管理端跟着掉线,帮村民录网格信息录到一半就没了。改成每端独立会话之后,同一账号在 PC 与手机上各持一份 token,互不干扰。

权限校验直接挂注解,业务代码里不用手写判断:

登录方式:短信验证码是主路径

村里用户群体的特点,决定了密码不是好选择。万村乐接的是阿里云短信接口,村民端主路径是手机号加验证码,后台账号才走账号密码。密码在传输前用国密加密,前端引的是 sm-crypto 0.3.11,后端对应 Smcrypto 0.3.2,避免明文密码走网络。

验证码这块有几个必须做的约束,不然容易被刷:

- 单手机号 60 秒内只能发一条,Redis 里放一个带过期的占位 key - 同一 IP 每天发送量设上限,超了直接拒绝并写操作日志 - 验证码 5 分钟过期,校验成功立刻删除,杜绝重放 - 连续 5 次校验失败,锁定该手机号 30 分钟

单点登录:从村后台跳到大数据驾驶舱

万村乐的后台分总后台和村后台,每个级别独立账号管理,商业版及以上还带可视化大数据平台。用户的实际动线是在村后台点一下就要进大屏,中间再登一次会被投诉。这里用的是票据换会话,不把 token 直接甩到地址栏:

票据只活 30 秒,取完即删,即便被日志记下来也用不了第二次。相比把 token 拼在 URL 上的做法,这种方式在浏览器历史和 Nginx access log 里留不下可复用的凭证。

数据权限拦截:村庄切换不能串数据

万村乐前端支持村庄切换并记录已访问的村庄,这个功能对后端的要求是每次请求都要明确当前上下文属于哪个村。做法是在 Sa-Token 的拦截器之后再挂一层数据权限拦截,把 villageId 从会话里取出来塞进 ThreadLocal,MybatisPlus 那边用租户插件自动拼条件:

镇县级账号是个例外,它的 village_id 是 0,需要跨村看数据,这类请求走单独的白名单方法并强制记录操作日志。

认证和留痕要连在一起

万村乐本身带日志统计能力,访问日志和操作日志都记,官方文档里的说法是责任追究到人、明确操作记录。要做到这一点,认证层就得把身份信息往下透传。我们的处理是在 Sa-Token 登录成功的回调里,把 userId、roleCode、villageId、终端类型一起写进 MDC,日志框架输出时自动带上,排查问题时按 userId 一捞就能还原整条操作链。

有一类问题在基层特别常见:村干部帮村民代操作。比如老人不会用手机,村干部在手机管理端替他提交事件反馈。这时候日志里要同时记录操作人和被操作人,只记一个都说不清楚。表里加 operator_id 和 target_user_id 两列,比事后翻聊天记录靠谱得多。

几条实践下来的经验

会话超时别一刀切。村民端 7 天、后台端 8 小时,是根据实际使用频率分开配的,村民一周登一次很正常,后台账号长期在线反而是风险。

角色粒度别做太细。万村乐村后台的角色是让村管理员自己建的,实际用下来,一个村常见就是村书记、文书、网格员这三四类,硬造出十几个权限点,村里没人会配。

游客态要提前设计。系统里村民分认证村民和游客两类,游客能浏览但不能发帖,这条规则如果等到功能都写完再补,前端每个页面都得改一遍。

短信通道要有降级。阿里云短信偶尔会有区域性延迟,界面上留一个语音验证码或者联系村管理员人工开通的兜底入口,比让用户干等强。

整套认证跑下来,改动量主要集中在会话策略和数据权限拦截这两处,业务代码基本没动。对于要覆盖多村、多端、多角色的数字乡村平台来说,把身份这层收干净,后面加模块才不会到处补权限判断。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档