电商平台就像一座日夜运转的线上商城,既要敞开大门迎接用户,又得时刻提防 "梁上君子"。账号被盗、数据泄露、支付欺诈 —— 这些安全威胁就像隐藏在角落的隐患,稍不注意就可能引发大麻烦。ZKmall开源商城没少在安全上花心思,它把 Shiro 安全框架和 JWT 认证机制拧成了一股绳,搭起了一套 "里三层外三层" 的防护体系。不管是 SQL 注入、XSS 攻击这些常见手段,还是暴力破解、身份伪造等恶意行为,都能被这套体系挡在门外,而且还不耽误用户购物的顺畅体验,真正做到了 "安全不啰嗦,便捷有保障"。

安全架构:Shiro 与 JWT 的 "分工协作"
ZKmall 的安全架构有个很清晰的思路:让专业的工具干专业的事。简单说,JWT 负责 "验明正身",确认你是系统里的合法用户;Shiro 负责 "划定边界",控制你能在系统里做什么。两者通过一个适配层无缝对接,形成了从登录到操作的完整安全闭环。
JWT 最让人省心的是它的 "无状态" 特性。以前用 session 认证,分布式系统里多台服务器得同步会话数据,麻烦不说还占资源。现在用户登录成功后,系统会生成一个包含用户 ID、角色信息的 JWT 令牌,就像给用户发了一张加密的 "电子身份证"。用户后续访问时,只要带着这张 "身份证",服务器不用查数据库就能认出是谁。不管用户用电脑、手机还是小程序登录,这张 "身份证" 都通用,跨端认证特别方便。
Shiro 则像个严格的 "门卫队长",手里攥着一本 "权限手册"。它的核心组件里,Subject 是用户的 "安全替身",负责发起登录、权限申请等操作;SecurityManager 是 "总调度",协调框架里的各种安全工具;Realm 则是 "信息库",专门从数据库或缓存里调取用户的权限数据。ZKmall 专门做了个自定义 Realm,能把 JWT 令牌里的信息翻译成 Shiro 能看懂的权限格式,让两个系统配合得严丝合缝。
它们的协作流程特别顺畅:用户登录时,Shiro 先核对用户名密码,没问题就叫 JWT 发 "电子身份证";用户操作时,JWT 过滤器先检查 "身份证" 是不是真的、有没有过期;通过后 Shiro 再对照 "权限手册",看用户能不能做这个操作 —— 能做就放行,不能做就拦下。就像进小区,先刷门禁卡验身份,再看是不是业主才能进单元楼,一环扣一环,既严谨又高效。

身份认证:把账号盗用的门焊死
账号认证是安全的第一道岗,ZKmall 在这上面下足了功夫。从 JWT 令牌的生成到 Shiro 的登录策略,每一步都卡得很严,让攻击者想偷账号都难。
JWT 的 "电子身份证" 制作得相当讲究。签名用的是 HMAC-SHA256 算法,密钥存在环境变量里,绝不会写死在代码里 —— 就像银行的金库钥匙,绝不会随便插在锁上。令牌还分了两种:access_token 有效期 2 小时,平时用;refresh_token 有效期 7 天,快过期了能自动换新版 access_token。这样既减少了长期令牌被盗的风险,又不用用户天天登录,体验没受影响。而且令牌里只放用户 ID、角色这些无关痛痒的信息,密码、手机号之类的敏感数据绝不放进去,就算令牌被偷,损失也有限。
为了防 "重放攻击"—— 也就是攻击者拿着偷来的令牌重复操作,系统搞了双重保险。每个令牌都有个唯一的 jti 标识,用户登出或改密码时,这个 jti 就会被扔进 Redis 黑名单,再用这个令牌就会被识破。更关键的是,支付、改密码这些敏感操作,光有令牌还不行,得额外输短信验证码或做人脸识别。有次测试团队模拟攻击,用偷来的令牌试了 10 次支付,全被验证码拦住了,根本没法得逞。
Shiro 在登录环节也守得很紧。用户密码不是明文存的,而是用 PBKDF2WithHmacSHA256 算法加 "盐" 哈希后才存进数据库。就算数据库被攻破,拿到的也是一堆乱码,想反推出原密码难如登天。登录失败 5 次就锁定 15 分钟,这个锁定状态存在 Redis 里,多台服务器都能共享,防止攻击者换个服务器继续试。要是检测到异地登录或新设备登录,系统会自动弹验证码,好多用户都说:"突然要验证码吓一跳,后来才知道是保护账号,挺安心的。"

权限控制:给数据加道 "专属锁"
越权访问是电商系统的大隐患 —— 比如普通用户偷看别人的订单,或者没权限的人改了商品价格。ZKmall 用 Shiro 把权限管得细之又细,确保每个用户只能碰自己该碰的东西。
Shiro 的权限设计像本详细的 "操作指南",格式是 "资源:操作"。比如 "order:view" 是查看订单,"product:edit" 是编辑商品。用户和权限通过角色挂钩,"admin" 角色能做所有事,"user" 角色只能看自己的订单。这种设计既好管理,又能精确控制范围,不会出现 "一刀切" 的情况。
URL 级别的控制就像 "大门岗"。配置文件里写着哪些 URL 需要哪些权限,比如 "/api/admin/*" 只有管理员能进,"/api/orders/\{id\}" 得有查看自己订单的权限。用户访问这些 URL 时,Shiro 会自动核对权限,没权限就返回 403。对于 RESTful 接口,还能校验路径参数 —— 比如查看订单时,确保订单 ID 属于当前用户,想偷看别人的订单门儿都没有。
方法级别的控制更像 "内部门卫"。在 Service 层的关键方法上标个注解,比如订单支付方法标了 "order:pay",就算有人绕过 URL 拦截,调这个方法时还是会被拦下。还有个自定义的 @DataPermission 注解,查询数据库时会自动加上 "user_id = 当前用户" 的条件,从根本上防止数据越权。有个开发新手忘了加这个注解,测试时普通用户居然能查到所有订单,多亏这个注解在生产环境起了作用,没造成事故。
JWT 在权限传递上也帮了大忙。令牌里带着用户的角色和权限摘要,服务器解析后不用每次都查数据库,授权速度快多了。要是权限变了 —— 比如管理员收回了某个权限,令牌里的版本号会跟着变,旧令牌就会失效,逼着客户端重新获取,保证用户的权限始终是最新的。
专项防御:见招拆招防攻击
网络攻击花样百出,ZKmall 针对常见的 SQL 注入、XSS、CSRF 这些手段,都有专门的防御招数,像个经验丰富的 "拆弹专家"。
防 SQL 注入有两招。Shiro 的过滤器先把用户输入里的单引号、分号这些危险字符过滤掉;业务层用 MyBatis 的参数化查询,绝不拼接 SQL 字符串。有次攻击者在搜索框里输入 "union select password from user",过滤器直接把 "union select" 给拦住了,日志里还记下了这次尝试,方便后续追溯。
XSS 攻击(跨站脚本)也很难得逞。用户输入时,Shiro 的 XSS 过滤器会把<script>这类标签转成安全字符;展示数据时,Vue3 框架会自动给内容编码,就算有漏网的脚本,也只会显示成文字不会执行。对于商品描述这种需要保留部分 HTML 的场景,只允许<b>、<i>这些安全标签,像<script>、<iframe>一概禁止,既满足业务需求又保安全。
CSRF 攻击(跨站请求伪造)基本没戏。JWT 令牌通常放在 Authorization 头里,跨站请求不会带这个头,天然就有防护作用。如果用 Cookie 存令牌,会加 SameSite=Strict 属性,只允许同站请求用。转账、改地址这些操作,还得输验证码,进一步降低风险。
DOS 攻击(拒绝服务)也扛得住。Shiro 的过滤器限制每个 IP 每秒最多发 10 次请求,超了就临时封禁;JWT 验证过的令牌会缓存起来,不用反复计算签名,省 CPU;大文件上传用分片加权限校验,防止恶意占用存储空间。上次大促有个 IP 疯狂发请求,不到 1 分钟就被封了,没影响到其他用户。
敏感数据保护更是重中之重。用户密码用 PBKDF2 加盐哈希,手机号、身份证号用 AES-256 加密存;传输全用 HTTPS,TLS 最低 1.2 版本,不安全的加密套件全禁用;JWT 里绝不放敏感信息。有次安全审计,审计员翻了半天日志,连个完整的手机号都没找到,直夸防护到位。
监控与应急:打造 "主动防御网"
安全防护不能光靠静态策略,还得能实时监控、快速响应。ZKmall 建了套 "安全预警系统",能及时发现攻击,迅速处置,把损失降到最小。
安全日志看得明明白白。Shiro 记录所有登录、授权操作,谁登录成功了、谁权限不够被拦了,都记着 IP、时间、用户 ID;JWT 的验证日志记着令牌是不是有效、签名对不对。这些日志用 ELK 栈集中管理,想查某天的异常登录,搜一下就出来。有次发现某个 IP 半夜总试登录,顺着日志一查,是台被黑客控制的肉鸡,赶紧封了。
实时监控像个 "千里眼"。Prometheus+Grafana 面板上,登录失败次数、权限校验失败次数这些指标看得一清二楚,超过阈值就报警。机器学习模型还会分析用户行为,比如突然从北京登录又瞬间到了美国,或者短时间查了上百个不同的订单,这些异常都会触发警报,准确率能到 95% 以上。
应急响应快如闪电。发现暴力破解,马上封 IP 并通知用户改密码;检测到伪造令牌,立刻吊销所有相关令牌,强制用户登出;有数据泄露风险,先停掉相关功能再启动预案。团队定期演练,上次模拟数据库被攻击,从发现到处置完只用了 40 分钟。
漏洞管理也不含糊。每周用 Nessus、OWASP ZAP 扫一遍漏洞,发现问题马上修;Shiro、JWT 有安全更新,24 小时内准换上;代码审计重点查认证授权、敏感数据处理,从源头堵漏洞。就像定期体检,小毛病早发现早治疗,免得拖成大病。

实战考验:从攻击中成长
去年大促期间,ZKmall 遭遇了一次集中攻击,正好检验了这套安全体系的成色。刚开始,攻击者用自动化工具暴力破解,10 分钟内发起了 10 万多次登录请求。Shiro 的登录限制立马生效,300 多个异常 IP 被封,被攻击的账号最多只失败了 5 次,没一个被盗。
接着,攻击者换招,在商品评价区发带恶意脚本的评论,想搞 XSS 攻击。大部分脚本被 Shiro 的过滤器拦了,但有一条用 HTML 实体编码绕过的评论发了出来。好在前端 Vue3 自动编码,脚本没执行。安全团队赶紧更新过滤器规则,把实体编码也纳入检测,彻底堵上了这个漏洞。
最后,攻击者尝试伪造 JWT 令牌访问管理员接口。但签名验证没通过 —— 他们用的密钥不对,JWT 过滤器直接拒了,还记了日志。监控系统发现短时间内大量令牌验证失败,马上报警。团队顺着 IP 查到了攻击源,最后通过法律手段制止了攻击。
这次事件后,系统又升级了:Shiro 的 IP 封禁策略更智能了,结合地理位置和攻击频率调整时长;JWT 的 payload 加了加密,就算令牌被偷,里面的信息也解不出来;XSS 过滤规则更全了,能识别更多绕过技巧。现在,系统对各种攻击的拦截率能到 99.9%,用户用着也更放心了。
安全是场持久战
ZKmall 用 Shiro 和 JWT 搭的安全体系,确实挡住了不少攻击,但安全这事儿没有一劳永逸的办法。攻击者的手段在变,防御策略也得跟着升级。未来可能会试试零信任架构,或者把生物识别加进来,让安全更智能。
对于开源社区来说,这套安全实践更有价值 —— 把配置、策略、应急流程整理成文档和模板,其他开发者拿来就能用,少走弯路。毕竟,电商系统的安全不仅关系到平台,更关系到每一个用户的信任。
说到底,安全和便捷不是对立面。ZKmall 的实践证明,只要架构设计得巧、策略用得妙,完全能做到既安全可靠,又不影响用户体验。在电商这个领域,赢得用户信任的第一步,就是让他们觉得 "在这儿购物,放心"。而这份放心,正是靠这些看不见的安全防线一点点筑牢的。