shiroマルチログインまたは重複ログイン禁止
テキストアドレス
目的:各ユーザは1つのセッションのみを使用可能にし、redisにも1つのセッションレコードしか使用できません.
プレゼンテーションのために
考え方:
欠点:ユーザー量が大きい場合は効率が低すぎる.
目的:各ユーザは1つのセッションのみを使用可能にし、redisにも1つのセッションレコードしか使用できません.
プレゼンテーションのために
Controller
階で直接制御します(私もどこで制御すべきかよく分かりませんが、ハハハ)考え方:
shiro
認証に合格した後、session
に現在登録されているアカウント(一意識別)を保存し、redis
に保存されているすべての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();
}