본문 바로가기

기타

[Backend] 인증 방식과 종류 (Session/Cookie, JWT)

728x90
반응형

 

 

계정 정보를 이용한 요청을 안전하게 처리할 수 있는 인증 방식에 대해서 공부하고 정리하는 시간을 가져보겠습니다.

 

 

더보기

아래의 글들을 참고하여 작성하였습니다.

tansfil.tistory.com/58

www.opennaru.com/opennaru-blog/jwt-json-web-token/

 

 

인증은 말 그대로 사용자가 누구인지 서버가 알 수 있도록 하는 것입니다.

예를 들어서 서버에 A 사용자에 대한 정보와 B 사용자에 대한 정보가 저장되어있을 때, 어플리케이션에서 특정 정보를 요청하였을 때, 이 요청한 사람이 A인지, B인지 식별하는 과정이 필요합니다.

 

하지만 현재 서버와 프론트 사이에서 이뤄지는 통신 방식인 HTTP는 이전에 주고 받았던 데이터들은 현재의 통신에 전혀 영향을 주지 않습니다.

즉, 어플리케이션에 로그인 할 때에는 A인지, B인지 알 수 있어도, 그 이후부터 이 사람이 A인지 B인지를 판단하는 것은 별개의 문제입니다.

 

따라서 우리는 HTTP 메세지의 헤더에 인증 수단을 넣어 요청을 보내는 방법을 사용합니다.

이러한 인증 방식은 여러가지가 있는데, 그 중에서 대표적인 3가지를 정리해보겠습니다.

 

 

 

 

헤더에 계정정보 등 인증을 위한 정보를 넣기

 

말 그대로 헤더에 해당 사용자의 아이디나 비밀번호와 같은 개인 정보를 직접 넣는 방법입니다.

이는 해당 정보를 탈취당하였을 때에 그대로 개인정보가 드러나기 때문에 보안에 좋지 않은 방법으로, 실서비스에서는 사용되지 않는 방식이라고 합니다.

 

 

 

 

Session과 Cookie

 

Session과 Cookie는 로그인과 같은 부분에서만 계정정보를 서버에 직접 보내고, 그 이후부터는 Session과 Cookie를 이용하여 사용자를 인증하는 방식입니다.

 

 

아래의 그림을 보면 좀 더 이해하기가 쉽습니다.

출처 : https://tansfil.tistory.com/58

 

즉, 존재하는 회원임을 확인하면, 해당 회원 정보에 대한 세션을 생성하여 이를 저장소에 저장하고, 클라이언트(사용자)에게는 Session ID(≒쿠키)를 발급하여 클라이언트에게 알려줍니다.

그러면 그 이후부터 클라이언트는 계속 계정 정보를 보내지 않고, 쿠키라는 것을 이용함으로써 자신이 누구인지 인증이 가능하게 됩니다.

발급받은 쿠키는 필요할 때에 서버에 함께 실어 보내 데이터를 요청합니다. 그러면 서버는 세션 저장소에서 해당 쿠키에 대응되는 세션을 찾고, 이 세션을 가지고 요청한 정보들을 찾아 데이터에 담고, 응답할 수 있게 됩니다. 

 

 

 

이러한 Session과 Cookie 기반의 인증 방식은 첫번째처럼 계정 정보가 아닌 단순한 값이기 때문에 로그인, 비밀번호처럼 정말 중요한 값은 아니죠.

 

하지만 이런 가정을 할 수 있습니다. 만약 누군가가 HTTP 요청을 탈취하여 쿠키값을 얻고, 이 쿠키를 이용하여 서버에 데이터를 요청하게 된다면?(=세션 하이재킹 공격)

서버에서는 해당 쿠키가 클라이언트로부터 온 것인지, 해커로부터 온 것인지 알 수 없기 때문에 데이터를 요청한 대로 응답하게 됩니다. 즉, 완전히 안전하다고는 할 수 없는 것이죠.

또한, 세션 정보를 저장하기 위한 저장소를 서버에 따로 두어야 하기 때문에 추가적인 부담이 생길 수 있습니다.

 

 

 

 

JWT로 불리는 토큰 기반 인증 방식

 

JWT는 Json Web Token의 약자로, 인증을 위해서 필요로 하는 정보들을 토큰으로 만들어 HTTP 헤더에 실어 보내는 방식입니다.

이러한 토큰을 만드는 데에는 크게 Header, Payload, Verify Signature가 필요합니다.

Header에는 Header, Payload, Verify Signature를 암호화할 방식, 타입등에 대한 내용이 들어갑니다.

Payload는 서버에서 보낼 데이터로, 유저의 고유 ID, 유효기간 등의 데이터가 들어갑니다.

Verify Signature은 base64방식으로 인코딩된  Header과 Payload와 함께 Secret Key를 더해 서명됩니다. base64 방식을 사용하기 때문에 URL에서 파라미터로 사용할 수 있어 URL-safe하고, 해시 암호화 알고리즘을 이용하여 암호화되어있습니다.

 

위의 Header과 Payload는 별도로 암호화를 진행하지 않기 때문에 별도의 장치가 없다면 디코딩만 하면 바로 정보가 드러나게 됩니다. 하지만 Verify Signature에서 사용하는 Secret Key를 모른다면 암호화된 Header와 Payload를 복호화 할 수 없도록 되어있습니다.

 

그러면 아래 그림의 왼쪽과 같이 인코딩된 토큰이 생깁니다.

 

https://jwt.io

Encoded 부분을 보면, 점을 기준으로 3구역이 나뉘어져 있는데 각각 인코딩된 header, payload, verify signature을 의미합니다.

이를 다시 디코딩하면 오른쪽과 같은 정보를 담고 있음을 알 수 있습니다.

 

이러한 토큰은 아래와 같은 흐름으로 진행됩니다. Session/Cookie 기반 방식과 흐름은 크게 다르지 않지만, 암호화가 되어있는 토큰을 사용한다는 것이 큰 차이점인 것 같습니다.

 

출처 : https://tansfil.tistory.com/58

 

 

JWT는 Session/Cookie 기반 인증처럼 세션 저장소를 따로 둘 필요 없이 단순히 해당 토큰이 옳은지 검증만 하면 되기 때문에 부담이 적습니다. 그 이유는 Session같은 경우는, 세션 저장소에서 쿠키를 가지고 아이디같은 정보를 조회하여야 하지만, Token은 필요한 정보를 Token 안에 다 담아두고 있기 때문입니다.

 

또한, 서명 부분에 누가 보냈는지와 보낸 정보에 대한 내용들이 포함되어 있기 때문에 중간에 데이터가 조작되거나 보낸 사람이 바뀌어도 이를 서버에서 알아차릴 수 있습니다.

 

하지만 Access Token은 유효기간이 정해져 있고, 이 유효기간 내에는 이를 계속 사용하기 때문에, 세션처럼 중간에 삭제하고 다시 발급받는 것이 어렵습니다. 따라서 이는 Refresh Token이라는 새로운 방식을 이용하여 보완합니다.

또한, 필요한 정보들이 Token에 넣어져 관리되어 크기가 커질 수 있고, 이를 요청에 계속 함께 실어 보내기 때문에 데이터 트래픽 크기에 영향을 줄 수 있습니다. 

728x90
반응형