解决shiro在前后端分离项目结合jwt鉴权出现的第一次请求限制资源报错404问题

前言

  • 本篇博客主要解决shiro在前后端分离项目应用中,结合jwt进行鉴权时,出现的第一次请求接口报错404问题

​ 查询网上资料,大部分是前后端不分离的解决方法,或是只描述问题并不给出解决方法,本文针对前后端分离情况,使用了 jwt 鉴权后,第一次请求接口不执行 shiro 的 AuthorizationInfo 方法,给出一个简便的解决方法。

白嫖容易,创作不易,若大家认为有用,学到知识,不妨点个赞

博客原创,转载请注明出处


背景描述

项目采用前后端分离模式,使用 SpringBoot + Shiro + Jwt 进行前后端分离鉴权,使用Swagger进行测试

此时登录通过校验用户名密码后返回 token,登录接口已在shiro配置中放行

    public R login(@Parameter(description = "用户名") @PathVariable String username, @Parameter(description = "密码") @PathVariable String password){
        User user = null;
        try {
            user = userService.findByUserName(username);
        } catch (Exception e) {
            e.printStackTrace();
            return R.error().message("用户名或密码错误!");
        }
        if (user == null) {
            return R.error().message("用户名或密码错误!");
        }
        if (!user.getPassword().equals(password)) {
            return R.error().message("用户名或密码错误!");
        }
        String token = TokenUtils.getToken(user.getUserId());
        return R.ok().data("token",token);
    }

问题描述

  1. 启动项目后,先进行登录
    在这里插入图片描述

  2. 随意选择一个接口进行测试
    在这里插入图片描述

  3. 结果出现404,但第二次就可正常执行
    在这里插入图片描述

  4. 查看后台日志可以发现,确实执行了认证方法
    在这里插入图片描述

  5. 继续查看发现,执行完认证方法后,并不执行授权方法
    在这里插入图片描述
    以下为认证方法部分代码

            //密码认证shiro做,由于该项目密码没有加密加盐,所以调用的是这个简单构造方法
            SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, useToken.getPrincipal().toString(), this.getName());
            System.out.println("=======================密码验证!");
            return info;
    

解决过程

查询各种博客资料后,发现了:shiro中的授权方法,即 AuthorizationInfo 方法,并不是执行认证后就会执行,而是访问限制资源时才执行。

这时我们回想我们的问题:登录后,第一次请求接口只认证不授权,但第二次后便恢复正常,第一次请求的接口也是限制资源,那为什么会出现这样的问题?

这时我们回想,在前后端不分离的项目中,没有使用 jwt 登录鉴权,这时的 shiro 登录是需要用到 subject.login 方法进行主动登录,而在前后端分离的项目中,我们并不需要这样进行,只需要在认证时校验用户即可。

由此我猜想,或许跟这个问题有关。


解决方法

直接在登录时采用原来的 subject.login 登录方式

    public R login(@Parameter(description = "用户名") @PathVariable String username, @Parameter(description = "密码") @PathVariable String password){
        User user = null;
        try {
            user = userService.findByUserName(username);
        } catch (Exception e) {
            e.printStackTrace();
            return R.error().message("用户名或密码错误!");
        }
        if (user == null) {
            return R.error().message("用户名或密码错误!");
        }
        if (!user.getPassword().equals(password)) {
            return R.error().message("用户名或密码错误!");
        }
        String token = TokenUtils.getToken(user.getUserId());
        Subject subject = SecurityUtils.getSubject();
        subject.login(new AuthToken(token));
        return R.ok().data("token",token);
    }

由此测试,加入这句登录代码后,在登录的时候便执行了一次认证,接着请求第二个限制资源时,便可以正常进行认证授权了。

由此猜测,shiro 的认证授权,是需要第一次认证后,shiro才能“记住这个用户”。因此以subject.login 方法来执行一次认证即可。

本人技术水平有限,难免出现逻辑不清晰或解释错误等问题,请大家包涵!可在评论区反馈

  • 9
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值