news 2026/9/2 23:20:19

[Day15] 若依框架二次开发改造记录:定制化之旅 contract-security-ruoyi

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
[Day15] 若依框架二次开发改造记录:定制化之旅 contract-security-ruoyi

目录

  1. 前言
  2. 项目背景
  3. 主要改造内容
    • 远程鉴权模块
    • JWT双Token认证机制
    • 游客登录功能
    • 内部服务免鉴权
  4. 技术要点总结
  5. 使用建议
  6. 写在最后

前言

近期在开展基于若依框架的项目时,面临一些特定业务需求,需进行定制化二次开发。在此记录主要改造工作,为有类似需求的朋友提供参考。需强调的是,本模块基于若依项目二次开发,仅作学习用途,不用于盈利。

项目背景

若依作为完善的后台管理框架,在实际项目中常遭遇特殊场景:

  • 多服务架构:主系统采用若依框架,同时存在其他独立部署的下游服务,需统一鉴权。例如,公司有一个核心业务系统基于若依搭建,还有一些辅助的数据分析、文件处理等下游服务,这些服务都要使用主系统的用户鉴权体系。
  • Token管理需求:下游服务采用双Token机制(Access Token + Refresh Token),以提升用户体验。
  • 游客访问:部分场景下,需允许未登录用户进行有限访问。就像一些电商网站,未登录用户也能浏览商品列表,但不能进行下单等操作。
  • 权限精细控制:需对内部服务调用进行特殊处理。

若直接在框架中开发项目固然理想,但由于微服务架构,若强行如此,就必须将鉴权代码复制多份分发到各个微服务中。基于这些需求,开展了一系列改造工作。

主要改造内容

一、远程鉴权模块

1.1 需求场景

项目中存在独立部署的服务,而用户体系需与主系统打通。若每个服务各自维护一套用户权限,管理成本将大幅增加。因此,需实现一种机制,让下游服务能通过网络调用主系统的鉴权接口验证用户权限,如同调用本地服务般便捷,且不改变原先鉴权注解的使用方式。

1.2 实现方案

整体架构如下:

有注解

无注解

通过

失败

下游服务请求

RemoteAuthFilter拦截

检查RemotePreAuthorize注解

提取Token

直接放行

Feign远程调用主系统

主系统验证权限

权限验证结果

继续执行业务逻辑

返回403拒绝访问

1.3 核心组件

新增ruoyi - feign模块,包含以下内容:

组件说明
@RemotePreAuthorize远程鉴权注解,用法与@PreAuthorize一致
RemoteAuthFilterServlet版鉴权过滤器
RemoteAuthWebFilterWebFlux版鉴权过滤器
RemoteAuthFeignServiceFeign客户端,调用主系统鉴权接口
UserFeignService用户相关的Feign客户端(暂未使用)
1.4 使用方式

在下游服务中,使用方式如下:

// 此代码展示了在下游服务的控制器中如何使用远程鉴权注解// 检查当前用户是否具有system:user:list权限@RestController@RequestMapping("/api/data")publicclassDataController{@RemotePreAuthorize("@ss.hasPermi('system:user:list')")@GetMapping("/users")publicList<User>getUsers(){// 业务逻辑,获取用户列表returnuserService.getUsers();}}

下游服务的配置也较为简单:

  1. 启动类增加@EnableFeignClients并且扫描路径包括com.ruoyi.feign.service
  2. 有一个最基本的SpringSecurityConfig配置类来覆盖若依的Security配置,否则可能会被拦截。
// 该配置类用于启动下游服务,并启用Feign客户端@SpringBootApplication@EnableFeignClients(basePackages="com.ruoyi.feign.service")publicclassDownstreamApplication{publicstaticvoidmain(String[]args){SpringApplication.run(DownstreamApplication.class,args);}}
1.5 支持的权限表达式

和原先的使用方式保持一致:

表达式说明
@ss.hasPermi('system:user:list')检查单个权限
@ss.hasRole('admin')检查单个角色
@ss.hasAnyPermi('system:user:add,system:user:edit')检查多个权限(满足其一即可)
@ss.hasAnyRoles('admin,manager')检查多个角色(满足其一即可)

二、JWT双Token认证机制

2.1 需求场景

下游服务的前端(此处称为Contract前端)采用JWT + Refresh Token的双Token机制:

  • Access Token:有效期较短(如30分钟),用于日常API调用。就像你去图书馆借书,短期的借阅证可以让你在一段时间内自由借阅书籍,但有效期一过就不能再借了。
  • Refresh Token:有效期较长(如7天),用于刷新Access Token。它类似于长期的会员证,在短期借阅证过期时,可以用来获取新的短期借阅证。

这样做有诸多好处:

  1. 短期Token泄露风险更小。
  2. 用户不需要频繁重新登录。
  3. Refresh Token可以在服务端主动撤销。
2.2 Token流转流程
数据库服务端前端数据库服务端前端日常API调用Token过期登录请求生成Access Token生成Refresh Token存储Refresh Token返回双TokenAPI请求(Access Token)返回数据刷新Token(Refresh Token)验证Refresh Token生成新Token对更新Refresh Token返回新Token对
2.3 核心实现

新增了JWT工具类,支持:

方法说明
generateAccessToken()生成Access Token
generateRefreshToken()生成Refresh Token
parseToken()解析Token
isAccessToken()判断是否为Access Token
isRefreshToken()判断是否为Refresh Token

同时新增了刷新令牌管理相关的Service:

  • SysRefreshToken:刷新令牌实体类
  • SysRefreshTokenMapper:Mapper接口
  • ISysRefreshTokenService:Service接口
2.4 新增接口
接口说明
POST /auth/refresh刷新Token
POST /auth/guest游客登录
GET /auth/getInfo获取用户信息(适配Contract前端)

三、游客登录功能

3.1 需求场景

某些场景下,希望允许未注册用户访问系统,但仅能进行有限操作,例如:

  • 查看公开数据。
  • 使用基础的分析功能。
  • 体验部分产品功能。
    这就需要游客登录功能。
3.2 实现方式

游客登录流程:

关闭

开启

前端发起游客登录

游客登录开关是否开启

返回错误提示

生成游客用户信息

分配默认游客角色

生成游客Token

返回游客身份信息

核心实现:

  • 游客用户特征:用户名为guest_+ 随机字符串。
  • 默认角色:GUEST角色。
  • 默认权限:只有查看和分析权限。
  • Token有效期:与普通用户一致。
3.3 使用方式

前端调用:

// 游客登录的前端请求示例// 向/auth/guest发送POST请求进行游客登录POST/auth/guest// 响应示例,返回游客相关信息{"code":200,"msg":"操作成功","data":{"user":{"id":"guest_123456","username":"guest_123456","role":"GUEST"},"accessToken":"xxx","refreshToken":"yyy","expiresIn":1800}}

系统配置:

-- 在sys_config表中添加配置,用于控制游客登录功能的开关INSERTINTOsys_configVALUES(100,'用户管理-游客账户','sys.account.guestLogin','false','是否开启游客登录功能','Y','admin',NOW(),'',NULL,'游客登录开关');

四、内部服务免鉴权

4.1 需求场景

某些内部服务之间的调用,如主系统调用下游服务,无需经过完整的用户权限验证。此时需要一种机制来识别并豁免这类请求。

4.2 实现方式

新增内部免鉴权配置,和鉴权中心使用同一个密钥进行比对。可能有人担心安全问题,实际上目前考虑到的风险是内部调用注册中心分发这段网络被劫持,不过若这段网络都被劫持,那需要担心的就不只是密钥泄露问题了。要明白攻防是资源的权衡,并非纸上谈兵,不必钻牛角尖。

# 内部服务免鉴权配置,配置密钥ruoyi:remote-auth:secret:SaltyFishSecretValue

通过特定的请求头或IP白名单来识别内部服务调用,跳过权限验证。

技术要点总结

1. 模块化设计

将远程鉴权功能独立成ruoyi - feign模块,带来诸多优势:

  • 代码结构清晰,各模块职责单一。
  • 其他服务引入使用方便。
  • 便于维护和升级。

2. 兼容性考虑

所有改造都确保与原若依框架兼容:

  • 原有的登录、鉴权方式不受影响。
  • 新功能通过开关控制,可灵活开启/关闭。
  • 下游服务和主系统可独立升级。

3. 安全性考虑

  • 采用Token过期机制。
  • 将Refresh Token存储在数据库,支持撤销。
  • 设置IP白名单限制。
  • 内部服务调用使用特定Token。

4. 用户体验

  • 双Token机制减少登录次数。
  • 游客功能降低使用门槛。
  • 统一的鉴权方式,提供一致的使用体验。

使用建议

1. 生产环境配置

  • 修改JWT密钥为强密钥。
  • 使用HTTPS传输Token。
  • 合理设置Token有效期。

2. 权限管理

  • 定期审查接口权限配置。
  • 严格限制游客权限。
  • 妥善保管内部服务Token。

3. 监控告警

  • 监控Token刷新频率。
  • 记录鉴权失败日志。
  • 设置异常访问告警。

写在最后

以上即为主要改造工作,整体未改变若依框架的核心设计理念,仅在特定场景下进行扩展与增强。若大家有类似需求,可参考这些改造方案,欢迎交流讨论。
下期老样子还是聊聊开发过程中遇到的一些问题。

标签:若依框架、二次开发、远程鉴权、JWT双Token、游客登录、内部服务免鉴权

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/29 13:40:35

[Day16] Bug 排查记录:若依框架二次开发中的经验与教训 contract-security-ruoyi

目录 前言Anonymous注解不生效 问题描述现象排查过程根本原因解决方案 游客登录后Token立即过期 问题描述排查过程根本原因解决方案预防措施 内部服务调用鉴权失败 问题描述排查过程根本原因解决方案 经验总结 接口设计配置管理监控和日志测试开发习惯 后续改进计划写在最后阶…

作者头像 李华
网站建设 2026/9/2 22:37:06

RLHF实战:解决大模型“幻觉“问题,提升Text-to-SQL准确率53%

文章分享了使用RLHF解决大模型Text-to-SQL任务中"幻觉"问题的实战经验。提出SFT冷启动PPO强化学习的两阶段训练方法&#xff0c;创新引入Router模型分解问题为路径选择和查询生成两步。通过保守PPO配置和分层奖励设计&#xff0c;路由准确率从35%提升至89%&#xff0…

作者头像 李华
网站建设 2026/8/29 13:15:35

Qwen3-VL-WEBUI极速体验:从注册到出图只要8分钟

Qwen3-VL-WEBUI极速体验&#xff1a;从注册到出图只要8分钟 1. 为什么选择Qwen3-VL-WEBUI&#xff1f; 想象一下&#xff0c;你是一位产品经理&#xff0c;突然被要求向投资人演示AI功能&#xff0c;而技术团队都在忙其他项目。这时候你需要一个"现在立刻马上"能跑…

作者头像 李华
网站建设 2026/9/2 22:53:18

Qwen3-VL教学实验室方案:50学生并发,成本比机房低70%

Qwen3-VL教学实验室方案&#xff1a;50学生并发&#xff0c;成本比机房低70% 引言&#xff1a;高校AI教学的痛点与破局 作为一名在AI领域深耕10年的技术专家&#xff0c;我完全理解高校老师在开设AI视觉课程时面临的困境。传统机房显卡性能不足&#xff0c;搭建本地实验室动辄…

作者头像 李华
网站建设 2026/9/2 22:46:08

Qwen3-VL表格提取最佳实践:免配置镜像省时90%

Qwen3-VL表格提取最佳实践&#xff1a;免配置镜像省时90% 1. 为什么财务人员需要Qwen3-VL表格提取 财务部门每天都要处理大量纸质报表、发票扫描件和Excel截图&#xff0c;传统OCR工具识别表格时经常出现以下问题&#xff1a; 合并单元格识别为多个独立单元格数字错位导致金…

作者头像 李华