shiroマルチログインまたは重複ログイン禁止


テキストアドレス
目的:各ユーザは1つのセッションのみを使用可能にし、redisにも1つのセッションレコードしか使用できません.
プレゼンテーションのためにController階で直接制御します(私もどこで制御すべきかよく分かりませんが、ハハハ)
考え方:shiro認証に合格した後、sessionに現在登録されているアカウント(一意識別)を保存し、redisに保存されているすべてのsessionを取得し、前回登録してセッションに保存した情報に基づいて前回保存したsessionを見つけ、redissessionを先に削除し、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();
}