저는 이전까지 Spring Security을 사용하여 jwt로 인증을 진행하였습니다. Json 로그인이 성공하면 accessToken과 refreshToken을 프론트에 발급해 주었으며, 서버에 접근하기 위해서는 헤더에 토큰 정보를 담아 요청하면 인증이 성공하여 Api로 원하는 동작을 수행하도록 구현하였습니다.
헤더에 토큰값을 넣어 인증하는 가장 간단하고 직관적인 방식이지만, 이번에 쿠키와 세션에 대해 공부하고 프론트와 협업해보며, 보다 안전하고 효율적인 로그인 방식을 구성해보기로 하였습니다.
이번 글은 스프링 시큐리티와 jwt를 활용한 인증 로직이 모두 구현 되어 있다는 전제 하에, 프로젝트를 진행하며 프론트와 협업시 쿠키와 세션, jwt를 어떻게 적절히 활용하면 좋을지에 대해 작성한 글입니다. 만약 Security와 jwt가 구현이 안되었거나 기초 개념이 헷갈리시는 분들은 먼저 아래 제가 벨로그에 작성한 시큐리티 시리즈를 참고하고 오시면 됩니다. 개념부터 구현까지 모두 작성되어 있습니다.
우선, 효율적인 인증 방법을 고안하기 위해서는 로그인은 어떤 방식으로 이루어 지는지, 쿠키와 세션, HTTP, JWT에 대한 기초적인 지식이 선행되어야 합니다. 하나하나 살펴보겠습니다.
JWT에 대해 제가 시큐리티 로그인 구현중 설명해놓은 글이 있습니다. 아래 글을 참고하시면 충분히 이해할 수 있을거라고 생각합니다.
클라이언트와 서버의 구조는 Request - Response 구조입니다. 클라이언트는 서버에 요청을 보내고, 응답을 대기하는 구조입니다. 이때 서버는 요청에 대한 결과를 만들어서 응답합니다. 이때 요청과 응답을 Http 프로토콜을 이용해 주고 받습니다.
이러한 특성때문에, 서버와 클라이언트가 통신을 할 때 통신이 연속적으로 이어지지 않고 한 번 통신이 되면 끊어지게 됩니다. 통신이 끊어지면 상태정보가 유지되지 않기 때문에 매번 페이지를 이동할 때마다 로그인을 다시 해야 하거나, 상품 선택 후 구매 페이지에서 선택한 상품의 정보가 없거나 하는 등의 문제가 발생할 수 있습니다.
HTTP 프로토콜의 번거로움과 불편함을 해결하기 위해 사용하는것이 바로 세션과 쿠키 입니다.
HTTP의 일종으로 사용자가 어떤 웹 사이트를 방문할 경우, 해당 사이트가 사용하고 있는 서버에서 사용자의 컴퓨터에 저장하는 작은 기록 정보 파일입니다. HTTP에서 클라이언트의 상태정보를 쿠키 형태로 클라이언트 PC에 저장하였다가 필요 시 정보를 참조하거나 재사용할 수 있습니다.
하지만 이 방식에는 심각한 보안 문제가 있습니다. 쿠키의 값은 임의로 변경될 수 있기 때문에, 클라이언트에서 강제로 다른 사용자로 변장할 수 있습니다. 또한 쿠키는 네트워크 전송 구간이나 로컬에서 탈취당할 수 있기 때문에, 중요한 정보(결제 정보 및 비밀번호 등)가 쿠키안에 있다면 큰 위협이 되며, 해커가 탈취한 쿠키는 악의적인 요청에 계속 사용될 수 있습니다.
이 문제를 해결하기 위해 다음과 같은 대안을 사용할 수 있습니다.
일정 시간 동안 같은 사용자(브라우저)로부터 들어오는 일련의 요구를 하나의 상태로 보고, 그 상태를 유지시키는 기술입니다. 여기서 일정 시간은 방문자가 웹 브라우저를 통해 웹 서버에 접속한 시점부터 웹 브라우저를 종료하여 연결을 끝내는 시점을 말합니다.
즉, 브라우저가 종료되기 전까지 클라이언트의 요청을 유지하게 해주는 기술을 세션이라고 합니다.
유니크한 세션 아이디를 쿠키에 담아 통신하는 방식입니다. 로그인이 성공한 후, 생성된 세션 ID가 세션 저장소에 있다면 ID를 쿠키에 담아 보내고, 없다면 새로운 세션 ID를 생성하여 쿠키에 담아 보냅니다.
사용자의 중요한 개인정보를 외부에 노출하지 않고, 서버에서만 다루기 위해 사용합니다.
쿠키와 세션의 차이점을 한 눈에 정리해보도록 하겠습니다.
Cookie | Session | |
---|---|---|
저장 위치 | Client | Server |
저장 형식 | Text | Object |
만료 시점 | 쿠키 저장 시 설정 (지정하지 않으면 종료시) | 정확한 시점 X |
리소스 | 클라이언트 리소스 소비 | 서버 리소스 소비 |
속도 | 쿠키에 정보가 담겨있어 비교적 빠름 | 정보가 서버에 있어 비교적 느림 |
세션과 쿠키를 하나만 사용하지 않고, 세션을 쿠키에 담아 사용하는 이유는, 세션이 쿠키에 비해 보안이 높은 편이나 세션은 서버에 저장되고, 서버의 자원을 사용하기 때문에 서버 자원에 한계가 있고, 속도가 느려질 수 있기에 쿠키를 같이 사용합니다.
자원관리 차원에서 쿠키와 세션을 적절한 요소 및 기능에 병행 사용하여 서버 자원의 낭비를 방지하며 웹사이트의 속도를 높일 수 있도록 해야 합니다.
이번 포스팅에서는 쿠키와 세션에 대해 알아보았습니다. 지금까지 공부한 내용을 바탕으로 생각한 로직은, 세션 ID라는건 결국 유저를 식별하기 위함이기 때문에 세션 아이디 대신, 서버에서 자체적으로 발급해주는 JWT 토큰을 쿠키에 설정해두어, 쿠키와 JWT인증 방식을 혼용하여 사용하면 될것 같다는 생각이 들었습니다.
그렇게 되면 매번 로그인 해야하는 수고도 덜고, 쿠키도 사용하며 보다 안전한 환경을 구축할 수 있겠다는 생각이 듭니다. 하지만, accessToken을 쿠키에 설정하여 그대로 사용하기에는 탈취당할 수 있는 문제점이 존재합니다.
따라서, 다음 포스팅에서는 다양한 보안 위협에 대해 알아보고, 어떤 방식이 가장 제가 진행하는 프로젝트에 적합할지 좀 더 고민을 거쳐 방식을 정하도록 하겠습니다. 이후에는 구체적인 구현과정과 코드를 함께 포스팅 하려고 합니다.
공부하며 작성한 내용이기 때문에, 혹시라도 잘못된 내용이 있으면 피드백 부탁드립니다. 다음 포스팅에서 뵙겠습니다.
참고
- https://velog.io/@octo__/%EC%BF%A0%ED%82%A4Cookie-%EC%84%B8%EC%85%98Session#%EC%84%B8%EC%85%98sessionhttps://velog.io/@kimdy0915/%EC%9D%B8%EC%A6%9D-%EB%B0%A9%EC%8B%9D%EC%BF%A0%ED%82%A4-%EC%84%B8%EC%85%98-JWT%EC%97%90-%EB%8C%80%ED%95%B4-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90#%EC%BF%A0%ED%82%A4cookie
- https://velog.io/@kimdy0915/%EC%9D%B8%EC%A6%9D-%EB%B0%A9%EC%8B%9D%EC%BF%A0%ED%82%A4-%EC%84%B8%EC%85%98-JWT%EC%97%90-%EB%8C%80%ED%95%B4-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90#%EC%BF%A0%ED%82%A4cookie
- 김영한님의 Http기초 강의