给财务主管角色加了凭证导出权限,后台角色页显示已勾选,前端刷了 5 次菜单里还是没有这一项,接口返回 403 并提示 permission denied: finance:voucher:export。重启一台实例后那台正常,另外两台照旧。碰到这种情况,我一般先确认改动有没有真的生效。
原因不复杂,权限集合按 userId 缓存在 Redis 里,键名只有用户 id,写入时没有带角色版本号。角色变更只更新了数据库,缓存里那份旧集合要等 TTL 到期才会被替换。
「权限缓存版本号」相关的日志我一般连着看前后五分钟,单看一条报错经常判断不出是哪一步失败。日志级别临时调高可以,记得改回去,长期开着既占磁盘又掩盖真问题。
redis-cli --scan --pattern 'perm:user:*' redis-cli DEL perm:user:88231 SELECT version FROM role WHERE id = 12;
具体做法是,缓存键拼上角色版本号 版本一变自然读到新键;角色权限保存成功后主动删掉相关用户的缓存;不要用模糊删除 按用户维度逐个删 避免扫全库。
最后用这个标准收尾,改完权限后刷新页面菜单立刻出现凭证导出,Redis 里该用户的键名后面带上了新的版本号。
