Spring/spring mvc 2 스터디

[Spring] 로그인 처리 세션

p8labs 2022. 5. 25. 23:20
728x90
반응형

로그인 처리 세션

앞서 쿠키로만 처리 하면 어떤 문제점들이 발생하는지 알아 봤다.

세션을 이용해서 해당 부분을 보완 해본다.

 

 

세션 동작 방식 로그인

  • 1. 로그인 요청
  • 2. 사용자 체크 
  • 3. 세션 아이디 생성
  • 4. 응답으로 생성된 쿠키를 헤더에 포함 시킨다.
  • 5. 쿠키가 브라우저의 쿠키 저장소에 등록이 된다

 

세션동작 방식 로그인 이후

  • 1. 페이지 접근
  • 2. 쿠키에 있는 세션 아이디로 실제 회원정보 조회
  • 3. 해당 정보를 가지고 화면에 보여준다.

 

세션으로 쿠키의 단점을 보완한점

  • 복잡한 세션Id 생성으로 쿠키값을 변조하여 접근하는것을 막는다.
  • 세션의 만료시간을 두어 쿠키가 탈취 되더라도 문제가 없도록 한다.

 

예제 코드

package hello.login.web.session;


import org.springframework.boot.web.servlet.server.Session;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Component;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.http.HttpRequest;
import java.util.Arrays;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

@Component
public class SessionManager {
    // 세션과 사용자 정보를 저장할 맵 선언
    private Map<String, Object> sessionStore = new ConcurrentHashMap<>();
  
    // 세션 쿠키 네임 선언
    public static final String SESSION_COOKIE_NAME = "mySessionId";


    // 세션 생성
    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 cookieSession = findCookie(request, SESSION_COOKIE_NAME);
        if (cookieSession == null) {
            return null;
        }
        return sessionStore.get(cookieSession.getValue());
    }

    // 세션을 소멸시킨다.
    public void expire(HttpServletRequest request) {
        Cookie cookie = findCookie(request, SESSION_COOKIE_NAME);
        if (cookie != null) {
            sessionStore.remove(cookie.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);

    }

}

 

 

HttpSession 이용하기

  • 실제 세션을 구현하는것은 힘들다. 
  • 서블릿에서 제공하는 세션을 사용하면 된다.
  • 그리고 시간이 지나면 알아서 자동으로 삭제를 해주는 기능을 제공해준다.

 

HttpServletRequest

  • 직접 HttpServletRequest 에서 세션을 가져오는 방식이다.
@GetMapping("/")
  public String homeLoginV3(HttpServletRequest request, Model model) {
HttpSession session = request.getSession(false); if (session == null) {
          return "home";
      }
      Member loginMember = (Member)
  session.getAttribute(SessionConst.LOGIN_MEMBER);
//세션에 회원 데이터가 없으면 home if (loginMember == null) {
          return "home";
      }
//세션이 유지되면 로그인으로 이동 model.addAttribute("member", loginMember); return "loginHome";
}

 

 

Session 생성과 조회

  • Session 이없는 경우 세션을 생성한다.
  • Session 조회 및 없을경우 생성
    - request.getSession(true)
  • Session 조회 및 없을 경우 생성 안함
    - request.getSession(true)
  • Session 에 정보를 저장
    - session.setAttribute(SessionConst.LOGIN_MEMBER, loginMember);
public String loginV3(@Valid @ModelAttribute LoginForm form, BindingResult bindingResult, HttpServletRequest request) {
        if (bindingResult.hasErrors()) {
            return "login/loginForm";
        }

        Member loginMember = loginService.login(form.getLoginId(), form.getPassword());
        if (loginMember == null) {
            bindingResult.reject("loginFail", "아이디 또는 비밀번호가 맞지 않습니다.");
            return "login/loginForm";
        }


        // 세션이 있으면 있는 세션 반환, 없으면 신규 세션을 생성
        HttpSession httpSession = request.getSession();

        // 세션에 로그인 회원 정보 보관
       httpSession.setAttribute(SessionConst.LOGIN_MEMBER, loginMember);

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

 

@SessionAttribute 

  • 세션을 생성하지는 않는다.
  • name 을 주어 찾을 세션을 가져온다.
    public String loginHomeV3Spring(
    @SessionAttribute(name = SessionConst.LOGIN_MEMBER, required = false)Member member, 
    Model model) 
    {
        if (member == null) {
            return "home";
        }

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

 

 

세션 타임아웃 설정

언제 세션을 종료해야 할지 정해야 한다.

  • 세션은 사용자가 로그아웃을 직접 호출해서 session.invalidate() 가 호출 되는 경우에 삭제된다.
  • 로그아웃 없이 종료 될경우 세션은 삭제 되지 않는다. 
  • 문제는 HTTP가 비 연결성(ConnectionLess)이므로 서버 입장에서는 해당 사용자가 웹 브라우저를 종료한 것인지 아닌지를 인식 할수 없다

 

세션의 종료 시점

  • 사용자가 서버에 최근에 요청한 시간을 기준으로 30분 정도를 유지해주는 것이다.
  • 이렇게 하면 사용자가 서비스를 사용하고 있으면, 세션의 생존 시간이 30분으로 계속 늘어나게 된다. 따라서 30분 마다 로그인해야 하는 번거로움이 사라진다. HttpSession 은 이 방식을 사용한다.

 

 

 

 

 

참고:

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-2/dashboard

 

스프링 MVC 2편 - 백엔드 웹 개발 활용 기술 - 인프런 | 강의

웹 애플리케이션 개발에 필요한 모든 웹 기술을 기초부터 이해하고, 완성할 수 있습니다. MVC 2편에서는 MVC 1편의 핵심 원리와 구조 위에 실무 웹 개발에 필요한 모든 활용 기술들을 학습할 수 있

www.inflearn.com

 

728x90
반응형