普兆健康管家后端代码仓库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

223 lines
6.3 KiB

  1. # AppletShiroRealm 触发问题分析
  2. ## 问题原因分析
  3. ### 1. 主要问题
  4. `AppletShiroRealm` 没有被触发的主要原因是:
  5. 1. **Shiro配置问题**: 在 `ShiroConfig.java` 中,`shiroFilter` 方法使用的是 `SecurityManager` 参数,但这个参数绑定的是 `securityManager` Bean,而不是 `appletSecurityManager`
  6. 2. **过滤器配置问题**: 虽然配置了 `AppletJwtFilter`,但它没有正确关联到 `AppletShiroRealm`
  7. 3. **用户服务接口问题**: `IAppletUserService` 的包路径发生了变化,导致依赖注入失败。
  8. ### 2. 具体问题点
  9. #### 2.1 Shiro配置问题
  10. ```java
  11. // 原来的配置
  12. @Bean("shiroFilterFactoryBean")
  13. public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
  14. // 这里使用的是 securityManager,而不是 appletSecurityManager
  15. }
  16. ```
  17. #### 2.2 过滤器链配置问题
  18. ```java
  19. // 小程序请求应该使用 appletApi 过滤器
  20. filterChainDefinitionMap.put("/appletApi/**", "appletApi");
  21. ```
  22. #### 2.3 用户服务依赖问题
  23. ```java
  24. // 原来的包路径
  25. import org.jeecg.modules.appletBackground.appletUser.service.IAppletUserService;
  26. // 修改后的包路径
  27. import org.jeecg.common.api.IAppletUserService;
  28. ```
  29. ## 解决方案
  30. ### 1. 修复Shiro配置
  31. #### 1.1 修改ShiroConfig.java
  32. -`shiroFilter` 方法中添加小程序登录接口的匿名访问配置
  33. - 确保小程序请求使用正确的过滤器
  34. ```java
  35. // 小程序登录相关接口不需要认证
  36. filterChainDefinitionMap.put("/appletApi/login/wxLogin", "anon");
  37. filterChainDefinitionMap.put("/appletApi/login/getPhoneNumber", "anon");
  38. // applet专用过滤器,只处理/applet开头的请求
  39. filterChainDefinitionMap.put("/appletApi/**", "appletApi");
  40. ```
  41. #### 1.2 修复AppletJwtFilter
  42. - 添加登录接口的匿名访问检查
  43. - 完善token验证逻辑
  44. - 增加详细的错误日志
  45. ```java
  46. // 检查是否是登录相关接口,这些接口不需要认证
  47. if (requestPath.startsWith("/appletApi/login/wxLogin") ||
  48. requestPath.startsWith("/appletApi/login/getPhoneNumber")) {
  49. return true;
  50. }
  51. ```
  52. ### 2. 修复用户服务接口
  53. #### 2.1 创建统一的IAppletUserService接口
  54. ```java
  55. package org.jeecg.common.api;
  56. public interface IAppletUserService {
  57. AppletUser getByOpenid(String openid);
  58. AppletUser getByPhone(String phone);
  59. boolean save(AppletUser user);
  60. boolean updateById(AppletUser user);
  61. }
  62. ```
  63. #### 2.2 实现服务类
  64. ```java
  65. @Service
  66. public class AppletUserServiceImpl extends ServiceImpl<AppletUserMapper, AppletUser>
  67. implements IAppletUserService {
  68. // 实现具体方法
  69. }
  70. ```
  71. ### 3. 修复AppletShiroRealm
  72. #### 3.1 完善用户获取逻辑
  73. ```java
  74. private AppletUser getAppletUser(String openid) {
  75. try {
  76. // 从数据库查询用户信息
  77. AppletUser appletUser = appletUserService.getByOpenid(openid);
  78. if (appletUser != null) {
  79. log.debug("从数据库获取到小程序用户: {}", appletUser.getName());
  80. return appletUser;
  81. }
  82. log.warn("未找到小程序用户,openid: {}", openid);
  83. return null;
  84. } catch (Exception e) {
  85. log.error("获取小程序用户信息异常,openid: {}", openid, e);
  86. return null;
  87. }
  88. }
  89. ```
  90. #### 3.2 完善权限配置
  91. ```java
  92. @Override
  93. protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
  94. SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
  95. // 小程序用户默认权限
  96. info.addRole("applet_user");
  97. info.addStringPermission("applet:user:*");
  98. return info;
  99. }
  100. ```
  101. ### 4. 修复服务层方法
  102. #### 4.1 使用AppletUserUtil获取当前用户
  103. ```java
  104. public Result<String> bindPhoneNumber(String phoneCode) {
  105. try {
  106. // 获取当前登录用户
  107. AppletUser currentUser = AppletUserUtil.getCurrentAppletUser();
  108. if (currentUser == null) {
  109. return Result.error("用户未登录");
  110. }
  111. // 其他逻辑...
  112. } catch (Exception e) {
  113. log.error("绑定手机号异常", e);
  114. return Result.error("绑定失败: " + e.getMessage());
  115. }
  116. }
  117. ```
  118. #### 4.2 简化控制器方法
  119. ```java
  120. @GetMapping("/getUserInfo")
  121. public Result<AppletUser> getUserInfo() {
  122. log.info("收到获取用户信息请求");
  123. return appletApiLoginService.getUserInfo();
  124. }
  125. ```
  126. ## 测试验证
  127. ### 1. 创建测试控制器
  128. ```java
  129. @RestController
  130. @RequestMapping("/appletApi/test")
  131. public class AppletTestController {
  132. @GetMapping("/getCurrentUser")
  133. public Result<AppletUser> getCurrentUser() {
  134. AppletUser currentUser = AppletUserUtil.getCurrentAppletUser();
  135. if (currentUser == null) {
  136. return Result.error("用户未登录");
  137. }
  138. return Result.OK("获取成功", currentUser);
  139. }
  140. }
  141. ```
  142. ### 2. 测试步骤
  143. 1. 先调用登录接口获取token
  144. 2. 使用token调用测试接口
  145. 3. 检查日志中是否有 `AppletShiroRealm` 的调试信息
  146. 4. 验证用户信息是否正确返回
  147. ## 关键修复点总结
  148. ### 1. 配置层面
  149. - ✅ 修复了Shiro配置中的过滤器链
  150. - ✅ 添加了小程序登录接口的匿名访问
  151. - ✅ 确保小程序请求使用正确的过滤器
  152. ### 2. 代码层面
  153. - ✅ 修复了用户服务接口的包路径问题
  154. - ✅ 完善了AppletShiroRealm的用户获取逻辑
  155. - ✅ 添加了详细的日志记录
  156. - ✅ 使用AppletUserUtil简化用户获取
  157. ### 3. 测试层面
  158. - ✅ 创建了测试控制器验证功能
  159. - ✅ 提供了完整的测试步骤
  160. ## 预期效果
  161. 修复后,当访问 `/appletApi/**` 路径的请求时:
  162. 1. **AppletJwtFilter** 会被触发
  163. 2. **AppletShiroRealm** 会进行用户认证
  164. 3. **AppletUserUtil** 可以正确获取当前用户
  165. 4. 日志中会显示相关的调试信息
  166. ## 注意事项
  167. 1. **包路径**: 确保所有相关的import语句都使用正确的包路径
  168. 2. **Bean注入**: 确保 `IAppletUserService` 的实现类被正确注册为Spring Bean
  169. 3. **数据库**: 确保 `applet_user` 表存在且有数据
  170. 4. **Redis**: 确保Redis服务正常运行
  171. 5. **日志级别**: 建议将 `AppletShiroRealm` 的日志级别设置为DEBUG,便于调试
  172. ## 调试建议
  173. 1.`AppletShiroRealm` 的关键方法中添加日志
  174. 2. 检查Spring Bean是否正确注入
  175. 3. 验证数据库连接和查询是否正常
  176. 4. 确认Redis缓存是否正常工作
  177. 5. 使用测试接口逐步验证功能