Shiro禁止多点登录或重复登录

原文博客地址

目的:每个用户只允许一个session可用,在redis中也只能有一条session记录

为演示直接在Controller层进行控制(我也不是很清楚应该在哪里进行控制,哈哈哈)

思路:shiro认证通过之后session中保存当前登录的账号(唯一识别),获取redis 中存的所有session,依据上次登录向session保存的信息找到上一次存的session,先删除redis中的session,在设置session失效。

缺点:用户量大的时候效率太低。

 @PostMapping("/login")
public Object login(String phone,String password) {
    System.out.println(password+phone);
    Subject subject = SecurityUtils.getSubject();
    UsernamePasswordToken upToken = new UsernamePasswordToken(phone, password);
    try {
        subject.login(upToken);
        // shiro认证通过之后 才进行session的替换
        if (subject.isAuthenticated()) {
            // 获取所有的session
            Collection<Session> activeSessions = sessionDAO.getActiveSessions();
            if(activeSessions.size() > 0) {
                activeSessions.forEach(session -> {
                // 找到当前phone的session(上一次存的session)
                if (phone.equals(session.getAttribute("phoneKey")) {
                    // 先在redis 中删除
                    sessionRedisTemplate.delete(AppConstants.SHIRO_SESSION_REDIS_PREFIX + session.getId());
                    // 在设置session失效,否则先失效就获取不到id了
                    session.setTimeout(0);
                }
            });
            }
        }

        /*向session中保存当前登录的手机号,以便检测是否登录过*/
        subject.getSession().setAttribute("phoneKey", phone);
    } catch (UnknownAccountException | IncorrectCredentialsException e) {
        return ResultEntity.error(ResultStatus.USERNAME_OR_PASSWORD_ERROR);
    }
    return ResultEntity.ok();
}
发布了7 篇原创文章 · 获赞 1 · 访问量 268

猜你喜欢

转载自blog.csdn.net/weixin_46235241/article/details/104108573