BackEnd/스프링 MVC

로그인 처리 - 세션 직접 만들어 보기

연향동큰손 2024. 12. 30. 23:56

세션을 직접 개발하여 적용 해보았다.

 

<SessionManager 전체 코드>

package hello.login.web.session;

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;

public class SesseionManager {
    public static final String SESSION_COOKIE_NAME = "mySessionId";
    private Map<String,Object> sessionStore = new ConcurrentHashMap<>();

    public void createSession(Object value, HttpServletResponse response){
        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){
        Cookie[] cookies = request.getCookies();
        if(cookies==null){
            return null;
        }
        return Arrays.stream(cookies)
                .filter(cookie -> cookie.getName().equals(cookieName))
                .findAny()
                .orElse(null);
    }
}

 

 

1. 세션을 생성하는 createSession 메서드

public void createSession(Object value, HttpServletResponse response){
    String sessionId = UUID.randomUUID().toString(); //추정 불가능한 랜덤 값 생성
    sessionStore.put(sessionId,value);
    Cookie mySessionCookie=new Cookie(SESSION_COOKIE_NAME,sessionId);
    response.addCookie(mySessionCookie);
}

 

여기서 value는 회원 객체에 해당한다.

 

2. 세션을 조회하는 getSession 메서드

public Object getSession(HttpServletRequest request){
    Cookie sessionCookie = findCookie(request,SESSION_COOKIE_NAME);
    if(sessionCookie==null){
        return null;
    }
    return sessionStore.get(sessionCookie.getValue());
}

클라이언트가 요청한 sessionId 쿠키의 값으로, 세션 저장소에 보관한 값 조회

 

 

3. 세션을 만료 시키는 expire함수

public void expire(HttpServletRequest request){
    Cookie sessionCookie = findCookie(request,SESSION_COOKIE_NAME);
    if(sessionCookie!=null){
        sessionStore.remove(sessionCookie.getValue());
    }
}

 

expire 함수를 통해 세션 저장소에서 세션을 삭제 가능

 

 

로그인 컨트롤러에서 사용하기 

@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());
    log.info("login? {}", loginMember);
    if (loginMember == null) {
        bindingResult.reject("loginFail", "아이디 또는 비밀번호가 맞지 않습니다.");
        return "login/loginForm";
    }
    //로그인 성공 처리
    //세션 관리자를 통해 세션을 생성하고 회원 데이터 저장

    sesseionManager.createSession(loginMember,response);
    return "redirect:/";
}

 

로그인 시 세션을 생성하는 로직을 추가해줬다.

 

 

 

로그아웃 구현

@PostMapping("/logout")
public String logoutV2(HttpServletRequest request) {
    sesseionManager.expire(request);
    return "redirect:/";
}

로그아웃에서 expire함수 호출

 

 

홈화면 컨트롤러에서 로그인 시 홈 화면에 유저명 띄우기도 가능하다.

@GetMapping("/")
public String homeLoginV2(HttpServletRequest request, Model model){

    Member member = (Member)sesseionManager.getSession(request);

    if(member==null){
        return "home";
    }

    model.addAttribute("member",member);
    return "loginHome";
}

 

 

로그인 후 홈 화면에서 쿠키값이 무작위 값과 함께 잘 넘어오는 것을 확인할 수 있다.