Spring 로그인처리 - 쿠키 / 세션 직접 작성해보기

UkJJang·2021년 9월 28일
0

인프런 김영한 님의 https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-2/dashboard 강의를 보며 학습했습니다.

스프링 로그인처리

  • 브라우저를 종료할 때 로그아웃이 되는 것을 원하기 때문에 영속쿠키, 세션쿠키 중에서 세션쿠키를 이용하여 로그인 처리를 한다.

쿠키 생성

        // 쿠키생성 : 쿠키에 시간정보를 주지않으면 세션쿠키(브라우저 종료시 모두 종료)
        Cookie idCookie = new Cookie("memberId", String.valueOf(loginMember.getId()));
        response.addCookie(idCookie);

쿠키 사용 방법

    @GetMapping("/")
    public String homeLogin(@CookieValue(name = "memberId", required = false) Long memberId, Model model) {
        if(memberId==null) {
            return "home";
        }

        // 로그인
        Member loginMember = memberRepository.findById(memberId);
        if (loginMember == null) {
            return "home";
        }

        model.addAttribute("member", loginMember);
        return "loginHome";
    }
  • @CookieValue 어노테이션을 사용하여 쿠키 값을 가져올 수 있다. 타입 컨버팅을 해주기 때문에 문자열 외에 숫자 타입으로도 가져올 수 있다.

로그아웃 - 쿠키없애기

    private void expireCookie(HttpServletResponse response, String cookieName) {
        Cookie cookie = new Cookie(cookieName, null);
        cookie.setMaxAge(0);
        response.addCookie(cookie);
    }

----------- 위에 방식은 보안상의 큰 문제가 있다.--------------

  • 개발자 도구 탭에서 해당 쿠키의 값을 변경할 수 있기 때문에 다른 사용자의 정보를 가져올 수가 있기 때문이다.

그렇기 때문에 쿠키에는 중요한 값을 노출하지 않고 예측 불가능한 임의의 토큰(랜덤 값)으로 노출시켜야 한다. 서버에서 토큰과 사용자 id를 매핑해서 인식한다. 그리고 서버에서 토큰을 관리한다.

세션

  • 서버에 중요한 정보를 보관하고 연결을 유지하는 방법

세션 직접 작성해보기

세션생성

    public static final String SESSION_COOKIE_NAME = "mySessionId";
    // 동시성 문제가 있을 경우
    private Map<String, Object> sessionStroe = new ConcurrentHashMap<>();

    /*
        세션생성
     */
    public void createSession(Object value, HttpServletResponse response)
    {
        // 세션 아이디 생성하고 값을 세션에 저장
        String sessionId = UUID.randomUUID().toString();
        sessionStroe.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 sessionStroe.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) {
            sessionStroe.remove(sessionCookie.getValue());
        }
    }

세션을 이용하여 로그인 회원인지 검증하는 방법

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

        // 세션 관리자에 저장된 회원 정보 조회
        Member member = (Member)sessionManager.getSession(request);

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

        model.addAttribute("member", member);
        return "loginHome";
    }
profile
꾸준하게 성실하게

0개의 댓글