로그인 처리하기 - 쿠키사용

Yangray·2021년 9월 3일
1

Spring 로그인 구현

목록 보기
1/4

로그인 정보는 어떻게 유지할까??
매번 쿼리 파라미터를 계속 유지하면서 넘겨주는 것은 매우 어렵고 번거롭다 이럴때 쿠키를 사용하면 된다.
쿠키란???

로그인 기능

LoginController - login()
로그인 성공시 세션 쿠키를 생성하자.

@PostMapping("/login")
public String login(@ModelAttribute LoginForm formHttpServletResponse response) {

 Member loginMember = loginService.login(form.getLoginId(),
form.getPassword());
  // 쿠키 생성 로직
 //쿠키에 시간 정보를 주지 않으면 세션 쿠키(브라우저 종료시 모두 종료)
 Cookie idCookie = new Cookie("memberId",String.valueOf(loginMember.getId()));
 response.addCookie(idCookie);
 return "redirect:/";
}
로그인 결과 view

쿠키가 저장된걸 볼 수 있다.

@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 를 사용하면 편리하게 쿠키를 조회할 수 있다.
  • 이때 로그인 하지 않은 사용자도 홈에 접근할 수 있기 때문에 required = false 를 사용한다
  • 로그인 쿠키(memberId)가 없는 사용자는 기존 home으로 보낸다. 추가로 로그인 쿠키가 있어도 회원이 아니면 home으로 보낸다.

로그아웃 기능

@PostMapping("/logout")
public String logout(HttpServletResponse response) {
//로그아웃시 쿠키를 response와 쿠키의 key를 넘겨 만료시키는 메서드 호출
 expireCookie(response, "memberId");
 return "redirect:/";
}

private void expireCookie(HttpServletResponse response, String cookieName) {
 Cookie cookie = new Cookie(cookieName, null);
 //세션 쿠키이므로 웹브라우저 종료시 서버에서 해당 쿠키의 종료 날짜를 0으로 지정
 cookie.setMaxAge(0);
 response.addCookie(cookie);
}
  • 로그아웃 방법은 다음과 같다

쿠키와 보안 문제

쿠키를 사용해서 로그인 id를 전달해서 로그인을 유지할 수 있다. 하지만 여기에는 심각한 보안 문제가 있다.

보안문제

1.쿠키 값은 임의로 변경할 수 있다.

   --- 클라이언트가 쿠키를 강제로 변경하면 다른 사용자가 된다.
   --- 실제 웹브라우저 개발자 모드 -> Application - > Cookie 변경으로 가능
   

2.쿠키에 보관된 정보는 훔쳐갈 수 있다.

  --- 만약 쿠키에 개인정보나, 신용카드 정보가 있다면???
  --- 이 정보가 웹 브라우저에 보관되고, 네트워크 요청마다 계속 클라이언트에서 서버로 전달된다.
  --- 쿠키의 정보가 나의 로컬 PC를 털릴 수도 있으며, 네트워크 전송 구간에서도 털릴 수 있다.
 --- 해커가 쿠키를 한번 훔쳐가면 평생 사용될 수 있다.
 
 

대안

-- 쿠키에 중요한 값을 노출하지 않고, 사용자 별로 예측 불가능한 임의의 토큰(렌덤값)을 노출하고, 서버에서 토큰과 사용자 id를 매핑해서 인식한다. 그리고 서버에서 토큰을 관리한다.
-- 토큰은 해커가 임의의 값을 넣어도 찾을 수 없도록 예상이 불가능 해야 한다.
-- 해커가 토큰을 털어가도 시간이 지나면 사용할 수 없도록 서버에서 해당 토큰의 만료시간을 짧게 유지한다. 또는 해킹이 의심되는 경우 서버에서 해당 토큰을 강제로 제거하면 된다.

정리

HTTP는 무상태 프로토콜이다. 따라서 클라이언트와 응답이 완료되면 연결을 끊는다.
그렇게되면 클라이언트가 페이지를 이동하게 되면 정보가 사라져 유지가 되지 않아 매번 정보를 링크나 body에 담아서 보내야하는 번거로움과 어려움이 발생한다.그래서 대안책으로 쿠키라는 저장소에 사용자 정보를 담아서 자동으로 요청할때마다 쿠키의 정보를 이용한다.하지만 심각한 보안문제를 초례한다. 쿠키는 노출이 되어있으며, 임의로 변경할 수 있고, 강제로 변경하면 다른 사용자가 되기 때문이다.이러한 보안문제의 대안으로는 쿠키에 중요한 값을 노출하지 않아야하며, 사용자 별로 예측 불가능한 임의의 토큰을 노출하고, 서버에서는 토큰과 사용자 id를 매핑해서 인식하고 서버에서는 이를 관리해야한다. 그리고 만약에 해커가 토큰을 털어가더라도 시간이 지나면 사용할 수 없도록 서버에서 해당 토큰의 만료시간을 짧게 유지해야한다. 또한 해킹이 의심되는 경우에는 해당 토큰을 서버에서 강제로 제거해야한다.

profile
시작은 미약하나 그 끝은 창대하리라

0개의 댓글