0
0

Session

Posted at
  • サーバーに重要な情報を保管し、接続を維持する方法である。
  • 前のCookieの解決を解決するためには、重要な情報はすべてサーバに保存し、クライアントとサーバは Session ID(推定不可能な任意の識別子値、UUID 等使用) にて接続しなければならない。 この方法をSessionという。
@PostMapping("/login")
public String login(@Valid @ModelAttribute LoginForm form, BindingResult bindingResult, HttpServletResponse response) {
    if (bindingResult.hasErrors()) {
        return "login/loginForm";
    }

    // 1. ユーザーがログイン情報(Login Form)を伝達すれば、サーバーで該当ユーザーであるか確認する。
    Member loginMember = loginService.login(form.getLoginId(), form.getPassword());

    if (loginMember == null) {
        bindingResult.reject("loginFail", "Dまたはパスワードが正しくありません。");
        return "login/loginForm";
    }

    sessionManager.createSession(loginMember, response);

    return "redirect:/";

}
@Component
public class SessionManager {

    public static final String SESSION_COOKIE_NAME = "mySessionId";
    // String : sessionId , Object : 値
    private Map<String, Object> sessionStore = new ConcurrentHashMap<>();

    // Session 生成
    public void createSesssion(Object value, HttpServletResponse response) {

        // 2.ユーザが正しければ、UUIDで推定できないsessionIdを作る。
        String sessionId = UUID.randomUUID().toString();
        // 3. sessionStoreを作り
        // セッションIDと値(login Member)を保存する。
        sessionStore.put(sessionId, value);

        // 4. サーバはsessionIdのみをCookeに入れてクライアントに渡す。
        Cookie mySessionCookie = new Cookie(SESSION_COOKIE_NAME, sessionId);
        response.addCookie(mySessionCookie);
    }
}

5.クライアントはCookieストレージにCookieを保管し、要求のたびにsessionIdを配信する。

  • クライアントとサーバは結Cookieを介して接続するが、推定不可能なsessionIdのみを入れて配信し、会員情報のような重要な情報は配信しない。

6.その後、サーバーはクライアントが伝達したsessionIdでsessionStoreに保管しておいたSession情報を照会する。

  • 長所
    • sessionIdがハッキングされても、ここには重要な情報がない。
    • sessionの満了時間を短く(ex。30分)設定すれば、sessionIdを盗んでも時間が経てば使用できなくなり、ハッキングが疑われる場合、サーバーから該当Session強制的に除去すれば良い。
@GetMapping("/")
public String homeLogin(HttpServletRequest request, Model model) {

    // クライアントが伝達したsessionIdで
    // sessionStoreに保管しておいたSession情報を照会する。
    Member member = (Member)sessionManager.getSession(request);

    //로그인
    if (member == null) {
        return "home";
    }

    model.addAttribute("member", member);
    return "loginHome";
}
@Component
public class SessionManager {

    // Sesssion 照会
    public Object getSession(HttpServletRequest request) {
        Cookie[] cookies = request.getCookies();
        if (cookies == null) {
            return null;
        }

        for (Cookie cookie : cookies) {
            if (cookie.getName().equals(SESSION_COOKIE_NAME)) {
                return sessionStore.get(cookie.getValue());
            }
        }
        return null;
    }
}

7.ログアウトするときは、sessionStoreにある値を削除すればよいが、Servletが提供するHttpSession(以後、別途ポスト作成)を使用すれば、invalidateメソッドを使用すればよい。

@PostMapping("/logout")
public String logout(HttpServletRequest request) {
    sessionManager.expire(request);
    return "redirect:/";
}
@Component
public class SessionManager {

    // Session 満了
    public void expire(HttpServletRequest request) {
        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                if (cookie.getName().equals(SESSION_COOKIE_NAME)) {
                    sessionStore.remove(cookie.getValue());
                }
            }
        }
    }
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0