未经过token验证的用户A使用正常用户登录后的有效token访问A自己的资源

用户ID和token:

已经登陆的用户:
{
    "status": 200,
    "msg": "登录成功!",
    "data": {
        "userId": "83c68099-6522-4d22-a841-7059089c18cd",
        "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6Ijgz
		YzY4MDk5LTY1MjItNGQyMi1hODQxLTcwNTkwODljMThjZCIsInR5cGUiOiLn
		lKjmiLciLCJleHAiOjE2NDY4MjA1MjgsImFjY291bnQiOiJhZW93dWd1b3poaS14eCJ9.QUuwS_24gJz7XxgHVUCDPGkGnp6j3e4p-lOHXpA_UeU"
    }
}

未进行登陆的用户:
userId:b3893569-94f2-420a-a3d3-827b6c8cafe6

在这里插入图片描述

使用未登录的用户ID登陆系统:
在这里插入图片描述
登陆一个正常使用的用户:
在这里插入图片描述

{
    "status": 200,
    "msg": "登录成功!",
    "data": {
        "userId": "83c68099-6522-4d22-a841-7059089c18cd",
        "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6Ijgz
		YzY4MDk5LTY1MjItNGQyMi1hODQxLTcwNTkwODljMThjZCIsInR5cGUiOiLn
        lKjmiLciLCJleHAiOjE2NDY4MjA1MjgsImFjY291bnQiOiJhZW93dWd1b3poaS14eC
        J9.QUuwS_24gJz7XxgHVUCDPGkGnp6j3e4p-lOHXpA_UeU"
    }
}

然后拿这个正常登录的用户的token去给未登录的用户进行token验证;
结果是拿到了未登录用户的个人信息。如下图A所示
图A

思考:为进行登录的用户可以拿着已经登录的用户的token进行访问自己的信息,这样河里吗?不河里!所以怎么办呢?
解决办法:
使用token里面PayLoad里的userId的信息,再次跟请求参数的userId验证一致性。
具体代码如下:
用户登录ServiceImpl:

    /**
     * 登陆用户,返回token。redis存放用户信息
     * @param account
     * @param password
     * @return token
     */
    @Override
    @Transactional(propagation = Propagation.SUPPORTS)
    public Map<String,String> login(String account,String password) {
        try{
            QueryWrapper<User> wrapper = new QueryWrapper();
            wrapper.eq("account",account).eq("password",MD5Utils.md5(password));
            User userDB = userdao.selectOne(wrapper);
//            User userDB = userdao.selectUsersByAccountPassword(account,MD5Utils.md5(password));
            if(userDB != null){
                //添加负载 Payload 不要放用户敏感信息
                Map<String,String> Payload = new HashMap<>();
                Payload.put("id",userDB.getId());
                Payload.put("account",userDB.getAccount());
                Payload.put("type", UserTypeEnum.USER.getName());
                String token = JwtUtil.createJwtToken(Payload, 120);//设置负载,设置token过期时间 120minutes
                redisTemplate.opsForValue().set(User.class.getSimpleName() + "_"+ userDB.getId(), GsonUtil.getGson().toJson(userDB));
                Map<String,String>map = new HashMap<>();
                map.put("token",token);
                map.put("userId",userDB.getId());
                return map;
            }
            throw new MsgException("登陆失败,用户名或密码错误");
        }catch (MsgException e){
            throw e;
        }catch(RedisConnectionFailureException e){
            log.warn(e.getMessage(),e);
            throw new MsgException("Redis缓存连接失败!");
        } catch (Exception e){
            throw e;
        }
    }

LoginInterceptor登录拦截器,做token检查的

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//        boolean token = (boolean)request.getAttribute("token");
        try{
            String token = request.getHeader("token");
            if(token == null || token.equals("")){
                throw new MsgException("未携带token");
            }
            //验证token正确性和是否过期了。
            JwtUtil.verifyToken(token);
            return true;
        }catch (MsgException e){
            throw e;
        }catch (JWTDecodeException e){
            throw new MsgException("token过期,请重新登录");
        }catch (TokenExpiredException e){
            throw new MsgException("token过期,请重新登录");
        }
        catch (Exception e){
            throw e;
        }
    }

JudgeUserIdUtil: 从HttpServletRequest里面的Header取出token,在从token的Payload取出userId,对比传入的userId。

public class JudgeUserIdUtil {

    public static Boolean Judge(HttpServletRequest request,String userId){
        String token = request.getHeader("token");
        DecodedJWT decodedJWT = JwtUtil.verifyToken(token);
        String userIdInToken = decodedJWT.getClaim("id").asString();
        if(userId.equals(userIdInToken)){
            return true;
        }
        return false;
    }
}

代码修改完毕后,当未登录的用户使用别人登录后的token进行访问系统,图A再次发送请求,系统会提示非法请求。
在这里插入图片描述
总结:
1,登录的时候将用户ID放进去Payload里
2,然后如果一些request请求有userId参数,那就使用token里Payload里取出userId2,
3,userId参数和userId2进行对比,如果一致那就OK,如果不一致那就不允许访问。

PS:或许我们可以使用sa-token来解决这样的问题?博主未学习sa-token,不敢断言。
以上博文若有言辞不当,望诸君不吝赐教。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值