[] 세션로그인
쿠키의 종류
-영속쿠키 : 만료 날짜를 입력하면 해당 날짜까지 유지된다
-세션쿠키 : 만료 날짜를 생략하면 브라우저 종료시 까지만 유지한다.
로그인 성공 시 세션쿠키 생성하기
//쿠키에 시간 정보를 주지 않으면 세션 쿠기(브라우저 종료시 모두 종료)
Cookie idCookie = new Cookie("memberId", String.valueOf(loginMember.getId()));
response.addCookie(idCookie);
ㄴ 로그인 성공 시 쿠키를 생성하고 httpServletResponse에 담는다
ㄴ 쿠키 이름을 memberId로 지정한다. 값은 회원의 id를 담아둔다.
ㄴ 웹 브라우저는 종료 전까지 회원의 id를 서버에 계속 보내준다.
ㄴ @coookieValue 로 쿠키 조회할 수 있음.
ㄴ로그아웃 추가
public String logout(HttpServletResponse response) {
expireCookie(response, "memberId");
return "redirect:/";
}
로그인 처리하기 - 세션 처리
세션의 동작방식
1) 사용자가 id ,pw를 전달하면 서버에서 사용자가 맞는지 확인한다.
2) 서버에서 세션id를 생성하고 저장소에 보관한다.
3) 서버가 클라이언트에게 mySessionid세션 id를 쿠키에 담아 전달하고, 클라이언트는 쿠키 저장소에 mySessionId 쿠키를 보관한다.
ㄴ회원과 관련된 정보는 전달하지 않고 세션 ID만 쿠키에 담아 전달한다.
4) 클라이언트는 요청시 항상 mySessionId 쿠키를 전달하고, 서버는 클라이언트가 전달한 mySessionId 쿠키 정보로 세션 저장소를 조죄하여 로그인시 보관하 세션 정보를 사용한다
로그인 - 세션관리 직접 구현
세션관리가 제공하는 기능
1) 세션 생성 ( sessionId를 추정불가능한 랜덤 값으로 생성한다 / 세션 저장소에 sessionId와 보관할 값을 저장한다 / sessionId로 응답할 쿠키를 생성하여 클라이언트에 전달한다. )
2) 세션 조회 ( 클라이언트가 요청한 sessionId 쿠키의 값으로 세션저장소에 보관한 값을 조죄한다 )
3) 세션 만료 ( 클라이언트가 요청한 sessionId 쿠키의 값으로 세션 저장소에 보관한 sessionId와 값 제거
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";
// 스프링 아이디와 객체를 맵으로 저장
// 동시성을 위해 ConcurrentHashMap<>() 사용
private Map<String, Object> sessionStore = new ConcurrentHashMap<>();
/**
* 세션 생성
*/
public void createSession(Object value, HttpServletResponse response) {
// 세션 id를 생성하고, 값을 세션에 저장
// randomUUID() : 확실한 랜덤값을 얻을 수 있음. 자바가 제공
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 void expire(HttpServletRequest request) {
Cookie sessionCookie = findCookie(request, SESSION_COOKIE_NAME);
if (sessionCookie != null) {
// 만료된 쿠키를 지움
sessionStore.remove(sessionCookie.getValue());
}
}
// 쿠키를 찾는 로직
public Cookie findCookie(HttpServletRequest request, String cookieName) {
if (request.getCookies() == null) {
return null;
}
return Arrays.stream(request.getCookies())
.filter(cookie -> cookie.getName().equals(cookieName))
.findAny()
.orElse(null);
}
}