SaToken权限认证错误:NotLoginException-未能读取到有效token-可能是远程调用出现了错误

一:权限认证出现:NotLoginException-未能读取到有效token错误

在权限认证之前,登录认证已经写完了,而且没有错误:

1.使用apifox进行登录测试

 2.登录成功后会发现在Header中有set-cookie,会自动生成satoken

 3.并将session和token都存到redis中

登录成功!!!

2.权限认证

①新建一个类,实现 StpInterface接口(这里面有伏笔,错误就在这)

public class StpInterfaceImpl implements StpInterface {

    @Resource
    private WebAccountFeignClient webAccountFeignClient;

    /**
     * 返回一个账号所拥有的权限码集合
     */
    @Override
    public List<String> getPermissionList(Object loginId, String loginType) {
        List<Dict> dictList = webAccountFeignClient.queryPermissionInfo(loginId.toString());
        return dictList.stream().map(m -> m.getStr("code")).toList();
    }

    /**
     * 返回一个账号所拥有的角色标识集合 (权限与角色可分开校验)
     */
    @Override
    public List<String> getRoleList(Object loginId, String loginType) {
        List<Dict> dictList = webAccountFeignClient.queryRoleInfo(loginId.toString());
        return dictList.stream().map(m -> m.getStr("id")).toList();
    }

}

②开始对权限认证进行测试,测试类为TestController

@RestController
@RequestMapping("/test")
public class TestController {

    @GetMapping("/select")
    public String select() {
        System.out.println("is login:" + StpUtil.isLogin());
        System.out.println("loginId:" + StpUtil.getLoginId());
        StpUtil.checkLogin();
        StpUtil.getTokenValue();
        System.out.println("获取权限集合" + StpUtil.getPermissionList());
        return "success";
    }

}

 在登录的状态下,其他代码都是正确的,只有 StpUtil.getPermissionList() 是错误的,而且错误是

 通过定位到这段代码--打开注解式鉴权出现了错误

@Slf4j
@EnableWebMvc
@Configuration
public class AuthModuleConfig implements WebMvcConfigurer {

    /**
     * 注册 Sa-Token 拦截器,打开注解式鉴权
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        log.info("AuthModule - Interceptor - SaToken");
        registry.addInterceptor(new SaInterceptor(handle -> StpUtil.checkLogin())) // 登录校验
                .addPathPatterns("/**") // 拦截所有
                .excludePathPatterns("/userInfo/login"); // 排除部分
    }
}

 这就导致我当时很蒙,因为通过checkLogin方法已经判断,登录成功了,但是一获取权限集合就出现错误,这是为什么呢?我也看过文档,搜过文章,但是还是没有成功。

注:文档的几种可能的错误--》传送门:Sa-Token

这几种错误能够解决很大部分的错误,但是没有解决掉我的问题。这里就要谈到之前的伏笔了,错误所在处,项目分成了很多的模块,我将关于satoken相关的代码都写在了auth模块中,而我在web-account模块中做的测试,所以者之间涉及到了远程调用,我使用的是fegin进行远程调用。

@Component
@FeignClient(value = "cxqx-web-account")
public interface WebAccountFeignClient {

    /**
     * 获取角色信息
     *
     */
    @LoadBalanced
    @GetMapping("/roleInfo/selectRoleInfo")
    List<Dict> queryRoleInfo(@RequestParam("loginId") String loginId);

    /**
     * 获取权限信息
     *
     */
    @LoadBalanced
    @GetMapping("/permissionsInfo/selectPermissions")
    List<Dict> queryPermissionInfo(@RequestParam("loginId") String loginId);

}

 这就是错误所在之处:Feign远程调用时会丢失请求头的问题

相关的文章:Feign远程调用丢失请求头问题以及异步丢失上下文问题解决方法_lovoo的博客-CSDN博客微服务feign调用时候,token丢失问题解决方案_feign远程调用丢失token_zero _s的博客-CSDN博客

feign远程调用属于http请求,他是不会携带之前的token的,而我在没有进行feign调用的时候,登录是成功的,一进行远程调用就出现错误(等下会说到如何找到这个错误的,会涉及到satoken的一点源码),那是因为远程调用,请求了接口,被拦截了下来,需要进行登录检验,而feign请求又不会携带token,导致我出现了未获得有效token的情况。

二:我是如何发现是feign远程调用的错误呢?

此处涉及到了一些源码,我在获取权限集合的时候他总是会跳转到(satoken的好处就是国内的框架,注释是中文的)

 发现getTokenValue最后返回的是null,所以我就在获取权限集合之前加了一行代码

StpUtil.getTokenValue();

 首先呢,会先跳转到

之后会跳转到

进入到StpLogic下的getTokenValue()方法中,发现token值能够被获取到,并且成功的返回了

此时我就在想,既然getTokenValue()可以成功返回,但是为什么我一获取权限集合 :StpUtil.getPermissionList() 在getTokenValue() 中就会返回null呢?那么就在获取权限集合处再打个断点试试。

会先进入 StpLogic类下的getPermissionList()方法

再进入StpLogic类下的getLoginId()方法,此时的token是获取成功了的,也成功的返回了 

 

之后会再去调用,此时参数都是正常的,我成功的获取到了

再然后就是进入到我重写的这个类中

执行这个远程调用的时候,发现再一次的跳转到

因为feign远程调用属于http请求,并且会调用一次web-account模块中的接口,所以就会被拦截器拦下,进行登录校验,而这次登录校验,并未获取到token。所以我就想到了可能是远程调用出现了问题,就去查了些资料,就是上面看到的,feign进行远程调用是不会携带原来的token的,所以登录检验失败。

那么问题找到了,就需要解决了,只需要 在拦截器中加上feign的拦截器,让他携带原来的token即可。最后问题成功的解决。

解决办法代码:

/**
     * feign远程调用丢失上下文的解决方案,新增拦截器
     */
    @Bean("/requestInterceptor")
    public RequestInterceptor requestInterceptor() {
        return (RequestTemplate requestTemplate) -> {
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            if (attributes != null) {
                HttpServletRequest request = attributes.getRequest();
                String token = request.getHeader("token");
                String cookie = request.getHeader("Cookie");
                String authorization = request.getHeader("Authorization");
                requestTemplate.header("token", token);
                requestTemplate.header("Cookie", cookie);
                requestTemplate.header("Authorization", authorization);
            }
        };
    }

我就马上的记录了一下这个错误,这个错误费了我接近一天的时间才解决,希望能够帮到和我出现同样错误的你!

 

  • 5
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值