프로젝트/텀블벅 클론 코딩

[ Spring / 사용자 인가 ] 1. 사용자 세션 부여하기

zangsu_ 2023. 6. 6. 10:47

일반적으로 로그인이 필요한 웹 서비스의 경우 사용자의 요청에 대한 인증/인가를 구현해 둔다. 이번 단계에서는 그 중에서도 사용자의 요청에 대한 인가(Authorization)를 구현한 과정을 정리한다.

 

서론

간단하게 말하자면, 인증은 로그인을 하는 과정에 해당한다. 사용자가 입력한 아이디, 비밀번호를 이용해 해당 사용자가 회원임을 확인하는 과정이다. 그리고, 인가는 로그인 되어 있는 회원의 권한을 유지시켜 주는 과정과 관련이 있다.

일반적으로 특정 행동에 대해 사용자의 계정 권한이 필요한 웹 서비스의 경우 사용자의 권한을 유지시켜 줄 필요가 있다. 만약 사용자의 권한이 유지가 되지 않는다면, 우리가 어떤 웹 서비스에 이미 로그인을 했더라도 글 작성을 하는 등의 사용자 권한이 필요한 동작을 할 때 다시 우리의 신원을 확인시켜 주어야 한다. 이는 상당히 번거로우며, 때문에 웹 서비스는 다양한 방법을 이용해 사용자의 권한을 유지시켜 준다.

 

사용자의 회원가입 성공 / 로그인 성공 상황에서 권한을 부여하고, 해당 권한을 이후의 요청에서 유지 시켜 주는 방법을 구현해 보자.

 

권한 유지 방법

이번에는 여러 방법 중 세션을 이용하는 방법을 선택하였다. 그 이유는 아래와 같다.

 

1. Cookie만을 이용해 사용자의 권한을 부여하는 것은 보안상의 문제가 존재했다.

이를테면 제 3자가 해당 쿠키를 중간에 가로챈다면 특정 유저의 권한 정보가 유출 된다. 또, 이미 유출 된 사용자의 정보를 이용하여 쿠키를 수정, 생성 후 서버에 요청하게 된다면 제 3자가 특정 유저의 권한을 탈취할 수 있다. 즉, 민감한 정보를 서버 외부에 사용하게 되는 것이다. 또, 쿠키는 권한 확인을 위한 정보가 사용자의 환경에서 저장되기 때문에 사용자 권한 유지 여부를 서버에서 관리하기가 어렵다.

 

2. JWT 토큰을 사용하는 방법은 생소하다.

물론 다양한 기술 사용을 통해 성장하는 것이 이번 프로젝트의 주 목적이었지만, 동작 과정이 아직 어색한 JWT 토큰을 사용하기 위해서는 러닝커브가 존재할 것이고 프로젝트 기간이 얼마 남지 않은 상황에서 좋은 선택은 아니라고 생각했다.

 

3. 세션은 서버에서 권한을 관리한다.

세션을 사용하게 되면 권한 확인에 사용되는 값은 서버에 저장된다. 이 때 세션 ID가 저장되는 값의 탐색을 위한 key로 생성이 되며, 사용자에게는 해당 세션 ID값을 전달해 준다. 다음 요청부터는 사용자는 쿠키를 이용해 세션 ID를 전달하게 되며 서버에서는 해당 세션 ID에 매핑되는 권한이 저장되어 있는지 확인하게 된다.

즉, 민감한 정보가 서버 외부까지 사용되지 않으며 세션 역시 서버에서 관리되기에 사용자 권한 관리에 용이해진다.

 

세션 구현

HttpRequest에서 세션을 얻기 위해 getSession() 메서드를 호출하게 되면 세션이 존재하는 경우 해당 세션을 반환, 존재하지 않는 경우 기본적으로 새로운 세션을 생성해 준다. Spring에서는 요청에 대한 메서드에서 HttpSession 변수를 파라미터로 선언해 두면 해당 위의 과정을 진행한 이후의 결과 세션을 바로 넘겨준다.

로그인/회원가입 메서드에서 올바른 요청에 대한 응답으로는 해당 사용자의 index 값을 세션에 저장한 후 세션 Id를 클라이언트에게 넘겨주는 것으로 구현 하자.

 

//...//
    @PostMapping
    public ResponseEntity signUp(
    	@RequestBody UserReceivingDTO newUserDTO, HttpSession session) {

        long userIndex;
        try {
            userIndex = userService.join(newUserDTO);
        } catch (TumblbugException e) {
            return ResponseEntity
                    .status(e.getErrorStatus())
                    .build();
        }

        session.setAttribute(HttpConst.SESSION_USER_INDEX, userIndex);
        session.setMaxInactiveInterval(60 * 60 * 24);
    }

위처럼 회원가입 성공 상황에 대해 세션을 생성 후 반환 해 주었다.

 

해치웠나...?

지금까지 물 흐르듯이 구현을 했다. 그리고, 로직 상에서 문제가 있는 부분은 없는 것 같다.

그럼 이제 회원가입을 성공 한 경우 JSESSIONID=~~ 라고 하는 쿠키가 생성되겠지????

 

그럴리가.

세상 일은 보통 생각대로 흘러가지 않는다.

이런!

분명 서버에서는 세션을 새로이 생성 해 주었기 때문에 Response의 헤더에 set-cookie 헤더를 추가했을 것이다. 그런데, 브라우저에서는 set-cookie 헤더를 확인할 수 없다!

 

글이 길어질 것 같으니 다음 글에서 잃어버린 set-cookie 헤더를 찾아보자.