当前位置: 首页 > article >正文

若依框架下JimuReport积木报表的Token安全集成实践

1. 若依框架与JimuReport积木报表的Token集成背景在企业级应用开发中报表系统往往是核心功能模块之一。JimuReport积木报表作为一款开源的报表工具以其灵活性和易用性受到开发者青睐。而若依RuoYi框架则是一个基于Spring Boot的快速开发平台两者结合能够快速搭建企业级报表系统。但实际开发中我们常常遇到这样的问题如何确保报表数据的安全访问特别是在前后端分离架构下传统的Session认证方式不再适用Token机制成为主流解决方案。我在多个项目中实践发现若依框架自带的Token认证体系与JimuReport的集成需要特别注意几个关键点JimuReport默认不携带Token认证机制若依的Token验证需要手动适配到报表接口前后端Token传递容易遗漏关键环节2. 后端Token认证实现详解2.1 核心接口分析与实现JimuReport主要涉及两个关键接口需要Token验证/jmreport/list- 报表列表查询接口/jmreport/view/*- 报表详情查看接口对于第一个接口我们需要实现JmReportTokenServiceI接口。这个接口是JimuReport提供的标准Token服务接口包含四个核心方法public interface JmReportTokenServiceI { String getUsername(String token); Boolean verifyToken(String token); String getToken(HttpServletRequest request); MapString, Object getUserInfo(String token); }具体实现时我建议创建一个JimuReportTokenService类注入若依的TokenServiceComponent public class JimuReportTokenService implements JmReportTokenServiceI { Autowired private TokenService tokenService; Override public String getUsername(String token) { LoginUser loginUser tokenService.getLoginUser(token); return loginUser ! null ? loginUser.getUsername() : null; } Override public Boolean verifyToken(String token) { try { LoginUser loginUser tokenService.getLoginUser(token); if(loginUser ! null){ tokenService.verifyToken(loginUser); return true; } return false; } catch (Exception e) { return false; } } Override public String getToken(HttpServletRequest request) { return TokenUtils.getTokenByRequest(request); } Override public MapString, Object getUserInfo(String token) { // 可根据需要返回用户扩展信息 return null; } }2.2 Token工具类优化原始代码中的TokenUtils可以进一步优化增加对多种Token传递方式的支持public class TokenUtils { private static final String[] TOKEN_HEADERS {token, Authorization, X-Access-Token}; public static String getTokenByRequest(HttpServletRequest request) { // 1. 检查URL参数 String token request.getParameter(token); if (StringUtils.isNotEmpty(token)) { return token; } // 2. 检查Header for (String header : TOKEN_HEADERS) { token request.getHeader(header); if (StringUtils.isNotEmpty(token)) { return token; } } // 3. 检查Cookie Cookie[] cookies request.getCookies(); if (cookies ! null) { for (Cookie cookie : cookies) { if (token.equals(cookie.getName())) { return cookie.getValue(); } } } return null; } }3. 接口安全拦截实现3.1 报表详情接口拦截器对于/jmreport/view/*这类动态路径接口我们需要自定义拦截器Component public class JimuInterceptor implements HandlerInterceptor { Autowired private TokenService tokenService; Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { response.setContentType(application/json; charsetUTF-8); String token TokenUtils.getTokenByRequest(request); try { LoginUser loginUser tokenService.getLoginUser(token); if (loginUser ! null tokenService.verifyToken(loginUser)) { return true; } } catch (Exception e) { // Token验证异常处理 } // 无权限响应 response.setStatus(HttpStatus.FORBIDDEN.value()); response.getWriter().write(JSON.toJSONString( AjaxResult.error(无权限访问报表数据))); return false; } }3.2 拦截器注册配置在若依框架中注册拦截器时需要注意排除静态资源路径Configuration public class WebConfig implements WebMvcConfigurer { Autowired private JimuInterceptor jimuInterceptor; Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(jimuInterceptor) .addPathPatterns(/jmreport/view/**) .excludePathPatterns(/static/**); } }4. 前端集成方案4.1 菜单嵌入与Token传递在若依Vue前端中我们可以通过iframe嵌入报表页面并自动附加Tokentemplate div classapp-container iframe :srcreportUrl frameborder0 stylewidth:100%;height:calc(100vh - 84px) /iframe /div /template script import { getToken } from /utils/auth import { getReportBaseUrl } from /api/jimu export default { name: JimuReport, data() { return { reportUrl: } }, created() { this.loadReportUrl() }, methods: { async loadReportUrl() { try { const baseUrl await getReportBaseUrl() this.reportUrl ${baseUrl}?token${getToken()} } catch (error) { this.$modal.msgError(报表加载失败) } } } } /script4.2 前端API封装建议将报表相关接口统一封装import request from /utils/request // 获取报表基础地址 export function getReportBaseUrl() { return request({ url: /ruoyi/jimu/baseUrl, method: get }) } // 获取报表列表地址带Token export function getReportListUrl() { return getReportBaseUrl().then(baseUrl { return ${baseUrl}/jmreport/list?token${getToken()} }) }5. 后端服务端配置5.1 报表服务配置类建议创建一个配置类集中管理报表相关参数Configuration public class JimuReportConfig { Value(${ruoyi.report.server}) private String reportServer; Value(${ruoyi.report.context-path:/jmreport}) private String contextPath; Bean public String reportBaseUrl() { return http:// reportServer contextPath; } }5.2 控制器实现报表基础地址控制器可以增加更多灵活性RestController RequestMapping(/ruoyi/jimu) public class JimuController { Autowired private JimuReportConfig reportConfig; GetMapping(/baseUrl) public String getBaseUrl() { return reportConfig.reportBaseUrl(); } GetMapping(/listUrl) public String getListUrl() { return reportConfig.reportBaseUrl() /jmreport/list; } }6. 配置文件优化在application.yml中建议采用以下配置结构ruoyi: report: server: 127.0.0.1:8080 # 报表服务器地址 context-path: /jmreport # 报表上下文路径 token: header-name: Authorization # Token请求头名称 param-name: token # URL参数名称 cookie-name: token # Cookie名称7. 常见问题与解决方案在实际项目中集成时我遇到过几个典型问题Token失效不跳转登录页解决方案是在前端增加Token失效检测window.addEventListener(message, (event) { if (event.data.type jimuTokenInvalid) { this.$modal.msgError(登录已过期请重新登录) this.$store.dispatch(LogOut).then(() { location.href /index }) } })报表加载跨域问题需要在Nginx配置中添加location /jmreport { proxy_pass http://report-server; add_header Access-Control-Allow-Origin $http_origin; add_header Access-Control-Allow-Credentials true; }报表导出权限控制需要在拦截器中增加导出路径判断if (request.getRequestURI().contains(/jmreport/export)) { // 额外权限校验逻辑 }8. 性能优化建议Token缓存优化在频繁访问报表时可以考虑缓存Token验证结果Override public Boolean verifyToken(String token) { String cacheKey report:token: token; Boolean cached redisCache.getCacheObject(cacheKey); if (cached ! null) { return cached; } boolean isValid //...验证逻辑 redisCache.setCacheObject(cacheKey, isValid, 5, TimeUnit.MINUTES); return isValid; }报表数据缓存对于常用报表可以启用JimuReport自带的缓存功能# application.properties jmreport.cache.enabledtrue jmreport.cache.time30m接口响应优化使用若依的注解缓存提升列表接口性能Cacheable(key jmreport:list: #token) public ListReportVO getReportList(String token) { // 查询逻辑 }这套集成方案在我负责的三个企业项目中稳定运行超过一年期间根据实际需求不断完善。特别是在金融行业项目中严格的权限控制要求促使我们对Token验证机制做了多次加固。建议开发者在实际应用中根据自身业务特点调整安全策略比如增加二次验证、操作日志记录等功能。

相关文章:

若依框架下JimuReport积木报表的Token安全集成实践

1. 若依框架与JimuReport积木报表的Token集成背景 在企业级应用开发中,报表系统往往是核心功能模块之一。JimuReport积木报表作为一款开源的报表工具,以其灵活性和易用性受到开发者青睐。而若依(RuoYi)框架则是一个基于Spring Boo…...

LeagueAkari:英雄联盟玩家的智能效率助手

LeagueAkari:英雄联盟玩家的智能效率助手 【免费下载链接】LeagueAkari ✨兴趣使然的,功能全面的英雄联盟工具集。支持战绩查询、自动秒选等功能。基于 LCU API。 项目地址: https://gitcode.com/gh_mirrors/le/LeagueAkari 还在为英雄联盟繁琐的…...

Docker挂载卷修改实战:3种方法解决路径变更难题(附详细步骤)

Docker挂载卷路径变更的实战指南:3种高效解决方案 每次项目结构调整时,最让我头疼的就是那些已经配置好的Docker挂载卷路径。上周迁移服务器时,我不得不面对十几个容器挂载路径的调整问题。经过反复尝试和踩坑,我总结出三种最实用…...

Windows服务器上的加密狗怎么共享给家里电脑用?保姆级配置USB Redirector和cpolar教程

专业软件加密狗远程共享全攻略:基于USB Redirector与cpolar的实战方案 1. 加密狗远程共享的核心价值与场景痛点 对于依赖专业软件的设计师、工程师和开发人员来说,软件加密狗往往是价值数万元的正版授权核心载体。传统工作模式下,这些物理加…...

从“厨房”到“餐厅”:用生活场景拆解CUDA、cuDNN与PyTorch的协作关系

1. 当深度学习遇上厨房:一场技术盛宴的幕后故事 想象一下你走进一家米其林餐厅,品尝到一道令人惊艳的料理。这背后需要什么?一个设备齐全的厨房、一套顺手的厨具、一把锋利的刀具,还有一份精心设计的菜谱。深度学习的世界也是如此…...

2024移动端UI设计趋势:除了深色模式,这些新规范你必须知道

2024移动端UI设计趋势:超越深色模式的五大革新方向 当设计师们还在为深色模式的适配问题焦头烂额时,移动界面设计的前沿已经悄然进化。Material Design 3和iOS 17带来的不仅是视觉语言的更新,更是一场关于人机交互本质的重新思考。从折叠屏的…...

UniGUI界面太单调?试试这个技巧:把Figma炫酷的按钮和卡片样式‘偷’过来

UniGUI界面改造实战:从Figma精准移植现代CSS样式 每次打开UniGUI项目,看到那些仿佛停留在2005年的默认控件样式,是不是有种想砸键盘的冲动?作为开发者,我们当然知道功能才是核心,但用户第一眼看到的永远是…...

Photoshop与EasyX结合:高效生成掩码图实现游戏透明贴图

1. 为什么游戏开发需要透明贴图技术 在开发2D小游戏时,角色和背景的融合是个常见需求。想象一下,如果你的游戏角色总是带着一个难看的白色矩形背景,那画面简直就像是从Windows 98时代穿越过来的。我刚开始做游戏时就犯过这个错误,…...

Innovus实战:如何用一条命令自动清理postRoute阶段冗余的PHC hold buffer?

Innovus实战:一键清理postRoute阶段冗余PHC hold buffer的高效方法 在数字IC后端设计的最后阶段,工程师们常常面临一个棘手问题:那些在postCTS阶段为修复hold违例而大量插入的PHC hold buffer,在完成布线后变得冗余,却…...

Arlec RC210 433MHz射频开关驱动开发与协议逆向

1. Arlec RC210开关模块底层驱动技术解析1.1 项目背景与硬件定位Arlec RC210系列是澳大利亚及新西兰Bunnings连锁建材超市主推的240V交流电源插座遥控系统,以单体(RC210)和三联装(RC213)形式销售。该产品线虽以Arlec为…...

如何下载低版本的maven

重新配置maven,需要下载maven,但是官网默认下载的是最新版,最新版不一定适合你,所以,我们一般会下载一些旧版的maven包,这篇文章简单介绍一下如何下载旧版本的maven。 先来看一下jdk 和maven的对应关系 M…...

Qwen3-Embedding-4B部署避坑指南:常见问题与解决方案汇总

Qwen3-Embedding-4B部署避坑指南:常见问题与解决方案汇总 1. 为什么你的Qwen3-Embedding-4B部署总出问题? 如果你正在尝试部署Qwen3-Embedding-4B这个强大的文本向量化模型,但总是遇到各种奇怪的问题,这篇文章就是为你准备的。我…...

代码仓库gitee的使用

1.gitee是什么 Gitee(码云)是国内最大的基于 Git 的代码托管与研发协作平台,由开源中国 2013 年推出,主打本土化、高速访问与全流程 DevOps 能力。 基本定位与规模 中文名:码云定位:国产代码托管、开源协…...

Sparthan Module电机控制库:五路闭环位置控制与UART协议解析

1. Sparthan Module 电机控制库技术解析Sparthan Module 是一款面向运动控制应用的嵌入式开发套件,其核心特征在于集成五路独立电机驱动通道,支持高精度位置控制。该模块采用 UART 作为主通信接口,通过串行协议与上位控制器(如 ES…...

DCT-Net快速上手:无需代码,网页上传照片立即体验卡通魔法

DCT-Net快速上手:无需代码,网页上传照片立即体验卡通魔法 1. 引言:零门槛的卡通化体验 想象一下,你刚拍了一张不错的自拍照,但总觉得少了点什么。如果它能变成卡通风格,会不会更有趣?或者&…...

SUNFLOWER MATCH LAB在Git版本控制下的协作开发流程

SUNFLOWER MATCH LAB在Git版本控制下的协作开发流程 如果你和团队正在开发一个像SUNFLOWER MATCH LAB这样的AI模型项目,可能已经体会过代码版本混乱、模型权重文件丢失、队友之间修改冲突的烦恼。今天咱们就来聊聊,怎么用Git这个工具,把这些…...

卡尔曼滤波调参避坑指南:从OpenCV代码反推Q/R矩阵设置技巧

卡尔曼滤波调参避坑指南:从OpenCV代码反推Q/R矩阵设置技巧 在目标跟踪、导航系统等实时应用中,卡尔曼滤波器的性能很大程度上取决于Q(过程噪声协方差)和R(测量噪声协方差)这两个关键参数的设置。许多开发者…...

ESP32蓝牙鼠标的5个实用场景:除了模拟点击还能做什么?

ESP32蓝牙鼠标的5个实用场景:除了模拟点击还能做什么? 当大多数人听到"蓝牙鼠标"时,想到的可能是办公室里那款无线外设。但将ESP32与蓝牙鼠标功能结合,却能打开一扇通往物联网创新应用的大门。这款成本不到50元的微控制…...

告别I2S DAC,用FPGA和Verilog实现PDM音频输出的保姆级教程(附完整代码)

用FPGA实现高保真PDM音频输出的全流程实战指南 在硬件开发领域,FPGA因其高度可编程性和并行处理能力,成为音频信号处理的理想平台。传统方案依赖专用I2S DAC芯片,不仅增加BOM成本,还限制了系统设计的灵活性。本文将手把手教你如何…...

Windows平台QGC地面站开发环境一站式部署指南(含Qt 5.15.2与源码实战)

1. Windows平台QGC地面站开发环境搭建概述 第一次接触QGroundControl(简称QGC)地面站开发的朋友,可能会被环境配置搞得头大。作为一款开源的无人机地面控制软件,QGC在Windows平台上的开发环境搭建确实需要一些技巧。我自己在配置…...

Qwen-Image效果展示:RTX4090D上Qwen-VL对中文菜单、路牌、说明书图像的理解

Qwen-Image效果展示:RTX4090D上Qwen-VL对中文菜单、路牌、说明书图像的理解 1. 开箱即用的视觉语言模型环境 在RTX4090D显卡上运行通义千问视觉语言模型(Qwen-VL)从未如此简单。这个定制镜像已经预装了所有必要的依赖环境,包括: CUDA 12.4…...

学术AI工具全解析:9大平台实现选题与降重无忧

工具对比排名表格 工具名称 核心功能 突出优势 Aibiye 降AIGC率 适配高校规则,AI痕迹弱化 Aicheck 论文降重 速度快,保留专业术语 Askpaper 论文降重 逻辑完整性好 秘塔写作猫 智能降重 结合语法检查 DeepL 多语言降重 翻译改写灵活 知…...

Spring Boot应用在K8s的探针配置全指南:从健康端点设计到生产级参数调优

Spring Boot应用在K8s的探针配置全指南:从健康端点设计到生产级参数调优 当Java微服务全面拥抱云原生时,Kubernetes探针配置成为保障服务稳定性的关键防线。不同于简单的存活检查,一套完善的探针体系需要与Spring Boot Actuator深度整合&…...

高效论文写作工具:9款AI助你突破开题与查重瓶颈

工具对比排名表格 工具名称 核心功能 突出优势 Aibiye 降AIGC率 适配高校规则,AI痕迹弱化 Aicheck 论文降重 速度快,保留专业术语 Askpaper 论文降重 逻辑完整性好 秘塔写作猫 智能降重 结合语法检查 DeepL 多语言降重 翻译改写灵活 知…...

避开这些坑!新手用股票API必知的5个隐藏成本(附沧海/麦蕊真实账单分析)

避开这些坑!新手用股票API必知的5个隐藏成本(附沧海/麦蕊真实账单分析) 在金融科技领域,数据是驱动决策的核心燃料。对于刚接触股票API的开发者或中小团队而言,表面上的报价单往往只是冰山一角。本文将揭示那些容易被忽…...

Vue Router 权限路由:动态路由、导航守卫与白名单的工程落地

Vue Router 权限路由:动态路由、导航守卫与白名单的工程落地 后台管理系统最常见的“前端安全”问题不是加密,而是权限: 登录后菜单如何按角色显示?直接输入 URL 能不能越权?刷新页面后动态路由丢失怎么办?…...

别再只会用df -h了!CentOS 7/8硬盘监控,这8个命令才是运维老鸟的秘密武器

别再只会用df -h了!CentOS 7/8硬盘监控,这8个命令才是运维老鸟的秘密武器 当服务器突然响应迟缓,或是收到磁盘空间告警时,大多数人的第一反应是执行df -h查看剩余空间。但真正的运维高手会告诉你,这仅仅是问题排查的起…...

自动驾驶中的LQR控制算法:从理论到实践的保姆级调参指南

自动驾驶中的LQR控制算法:从理论到实践的保姆级调参指南 当一辆自动驾驶汽车在复杂路况下保持车道时,方向盘背后隐藏的数学魔法往往来自一个经典控制理论——LQR(线性二次型调节器)。这个诞生于20世纪60年代的控制算法&#xff0…...

Axios 二次封装:拦截器、统一错误处理与文件下载

Axios 二次封装:拦截器、统一错误处理与文件下载 前端项目一旦接口多起来,就会出现这些痛点: 每个请求都要手动带 token401/500 的处理散落在各个页面文件下载(Excel)处理不统一,兼容性一堆坑 这篇给你一…...

Comsol模拟下的泰勒锥效应:探究耦合空间电荷密度与射流液滴断裂、内部回流动态行为——电纺丝...

comsol泰勒锥,耦合空间电荷密度,射流头部产生液滴断裂,内部回流,comsol静电纺丝,电喷墨电流体动力学仿真里有个经典场景——泰勒锥。玩过静电纺丝或者电喷墨的朋友都知道,当导电液体在高压电场下形成那个标…...