普兆健康管家后端代码仓库
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.
 
 
 
 
 
 

6.3 KiB

AppletShiroRealm 触发问题分析

问题原因分析

1. 主要问题

AppletShiroRealm 没有被触发的主要原因是:

  1. Shiro配置问题: 在 ShiroConfig.java 中,shiroFilter 方法使用的是 SecurityManager 参数,但这个参数绑定的是 securityManager Bean,而不是 appletSecurityManager

  2. 过滤器配置问题: 虽然配置了 AppletJwtFilter,但它没有正确关联到 AppletShiroRealm

  3. 用户服务接口问题: IAppletUserService 的包路径发生了变化,导致依赖注入失败。

2. 具体问题点

2.1 Shiro配置问题

// 原来的配置
@Bean("shiroFilterFactoryBean")
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
    // 这里使用的是 securityManager,而不是 appletSecurityManager
}

2.2 过滤器链配置问题

// 小程序请求应该使用 appletApi 过滤器
filterChainDefinitionMap.put("/appletApi/**", "appletApi");

2.3 用户服务依赖问题

// 原来的包路径
import org.jeecg.modules.appletBackground.appletUser.service.IAppletUserService;

// 修改后的包路径
import org.jeecg.common.api.IAppletUserService;

解决方案

1. 修复Shiro配置

1.1 修改ShiroConfig.java

  • shiroFilter 方法中添加小程序登录接口的匿名访问配置
  • 确保小程序请求使用正确的过滤器
// 小程序登录相关接口不需要认证
filterChainDefinitionMap.put("/appletApi/login/wxLogin", "anon");
filterChainDefinitionMap.put("/appletApi/login/getPhoneNumber", "anon");

// applet专用过滤器,只处理/applet开头的请求
filterChainDefinitionMap.put("/appletApi/**", "appletApi");

1.2 修复AppletJwtFilter

  • 添加登录接口的匿名访问检查
  • 完善token验证逻辑
  • 增加详细的错误日志
// 检查是否是登录相关接口,这些接口不需要认证
if (requestPath.startsWith("/appletApi/login/wxLogin") || 
    requestPath.startsWith("/appletApi/login/getPhoneNumber")) {
    return true;
}

2. 修复用户服务接口

2.1 创建统一的IAppletUserService接口

package org.jeecg.common.api;

public interface IAppletUserService {
    AppletUser getByOpenid(String openid);
    AppletUser getByPhone(String phone);
    boolean save(AppletUser user);
    boolean updateById(AppletUser user);
}

2.2 实现服务类

@Service
public class AppletUserServiceImpl extends ServiceImpl<AppletUserMapper, AppletUser> 
    implements IAppletUserService {
    // 实现具体方法
}

3. 修复AppletShiroRealm

3.1 完善用户获取逻辑

private AppletUser getAppletUser(String openid) {
    try {
        // 从数据库查询用户信息
        AppletUser appletUser = appletUserService.getByOpenid(openid);
        if (appletUser != null) {
            log.debug("从数据库获取到小程序用户: {}", appletUser.getName());
            return appletUser;
        }
        
        log.warn("未找到小程序用户,openid: {}", openid);
        return null;
        
    } catch (Exception e) {
        log.error("获取小程序用户信息异常,openid: {}", openid, e);
        return null;
    }
}

3.2 完善权限配置

@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
    
    // 小程序用户默认权限
    info.addRole("applet_user");
    info.addStringPermission("applet:user:*");
    
    return info;
}

4. 修复服务层方法

4.1 使用AppletUserUtil获取当前用户

public Result<String> bindPhoneNumber(String phoneCode) {
    try {
        // 获取当前登录用户
        AppletUser currentUser = AppletUserUtil.getCurrentAppletUser();
        if (currentUser == null) {
            return Result.error("用户未登录");
        }
        
        // 其他逻辑...
    } catch (Exception e) {
        log.error("绑定手机号异常", e);
        return Result.error("绑定失败: " + e.getMessage());
    }
}

4.2 简化控制器方法

@GetMapping("/getUserInfo")
public Result<AppletUser> getUserInfo() {
    log.info("收到获取用户信息请求");
    return appletApiLoginService.getUserInfo();
}

测试验证

1. 创建测试控制器

@RestController
@RequestMapping("/appletApi/test")
public class AppletTestController {
    
    @GetMapping("/getCurrentUser")
    public Result<AppletUser> getCurrentUser() {
        AppletUser currentUser = AppletUserUtil.getCurrentAppletUser();
        if (currentUser == null) {
            return Result.error("用户未登录");
        }
        return Result.OK("获取成功", currentUser);
    }
}

2. 测试步骤

  1. 先调用登录接口获取token
  2. 使用token调用测试接口
  3. 检查日志中是否有 AppletShiroRealm 的调试信息
  4. 验证用户信息是否正确返回

关键修复点总结

1. 配置层面

  • 修复了Shiro配置中的过滤器链
  • 添加了小程序登录接口的匿名访问
  • 确保小程序请求使用正确的过滤器

2. 代码层面

  • 修复了用户服务接口的包路径问题
  • 完善了AppletShiroRealm的用户获取逻辑
  • 添加了详细的日志记录
  • 使用AppletUserUtil简化用户获取

3. 测试层面

  • 创建了测试控制器验证功能
  • 提供了完整的测试步骤

预期效果

修复后,当访问 /appletApi/** 路径的请求时:

  1. AppletJwtFilter 会被触发
  2. AppletShiroRealm 会进行用户认证
  3. AppletUserUtil 可以正确获取当前用户
  4. 日志中会显示相关的调试信息

注意事项

  1. 包路径: 确保所有相关的import语句都使用正确的包路径
  2. Bean注入: 确保 IAppletUserService 的实现类被正确注册为Spring Bean
  3. 数据库: 确保 applet_user 表存在且有数据
  4. Redis: 确保Redis服务正常运行
  5. 日志级别: 建议将 AppletShiroRealm 的日志级别设置为DEBUG,便于调试

调试建议

  1. AppletShiroRealm 的关键方法中添加日志
  2. 检查Spring Bean是否正确注入
  3. 验证数据库连接和查询是否正常
  4. 确认Redis缓存是否正常工作
  5. 使用测试接口逐步验证功能