세션을 이용한 로그인 방법에 대한 내용입니다.
package hello.login.web.session;
import org.springframework.stereotype.Component;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
@Component
public class SessionManager {
public static final String SESSION_COOKIE_NAME = "mySessionId";
//HashMap을 써도 될 수 있지만 동시성(한번에 접속) 할 수 있을때는 ConcurrentHashMap이 좋다.
private Map<String, Object> sessionStore = new ConcurrentHashMap<>();
/**
* 세션 생성
* 세션 저장소에 sessionId 생성(임의의 추정 불가능한 랜덤 값)
* 세션 저장소에 sessionId와 보관할 값 저장
* sessionId로 응답 쿠키를 생성해서 클라이언트에 전달
*/
public void createSession(Object value, HttpServletResponse response){
//세션 id를 생성하고, 값을 세션에 저장
String sessionId = UUID.randomUUID().toString();
sessionStore.put(sessionId, value);
//쿠키 생성
Cookie mySessionCookie = new Cookie(SESSION_COOKIE_NAME, sessionId);
response.addCookie(mySessionCookie);
}
/**
* 세션 조회
*/
public Object getSession(HttpServletRequest request){
Cookie sessionCookie = findCookie(request, SESSION_COOKIE_NAME);
if (sessionCookie == null){
return null;
}
return sessionStore.get(sessionCookie.getValue());
}
public Cookie findCookie(HttpServletRequest request, String cookieName){
Cookie[] cookies = request.getCookies();
if (cookies == null){
return null;
}
return Arrays.stream(cookies)
.filter(cookie -> cookie.getName().equals(cookieName))
.findAny()
.orElse(null);
}
/**
* 세션 조회
*/
public void expire(HttpServletRequest request){
Cookie sessionCookie = findCookie(request, SESSION_COOKIE_NAME);
if (sessionCookie != null){
sessionStore.remove(sessionCookie.getValue());
}
}
}
// 세션 코드
@PostMapping("/login")
public String loginV2(@Valid @ModelAttribute LoginForm form, BindingResult bindingResult, HttpServletResponse response){
if (bindingResult.hasErrors()){
return "login/loginForm";
}
Member loginMember = loginService.login(form.getLoginId(), form.getPassword());
if (loginMember == null){
bindingResult.reject("loginFail", "아이디 또는 비밀번호가 맞지 않습니다");
return "login/loginForm";
}
//로그인 성공 처리
//세션 관리자를 통해 세션을 생성하고, 회원 데이터를 보관
sessionManager.createSession(loginMember, response);
return "redirect:/";
}
@PostMapping("/logout")
public String logoutV2(HttpServletRequest request){
sessionManager.expire(request);
return "redirect:/";
}