서버 인증 방식의 종류
- HTTP 의 특징으로 statless 와 connectionless 가 있습니다. 상태 및 접속 정보를 유지하지 않는다는 의미입니다.
- 서버에서 클라이언트를 식별하기 위한 간단한 방법은 사용자의 계정 정보를 사용하는 것이 있지만, 제 3 자에 의해 탈취되는 개인 정보 유출의 위험이 있기 때문에 보안 상 좋은 방법은 아닙니다.
- 위 문제를 해결하기 위한 2 가지 방법이 있습니다.
세션 및 쿠키 기반 인증
- 세션이란 서버가 저장하는 사이트 방문자들에 대한 기록입니다. id, ip주소, 마지막 방문은 언제인지, 어떤 브라우저를 사용했는지 등의 정보가 담겨 있습니다.
- 세션 및 쿠키를 이용한 인증 방식은 로그인 과정에서만 계정 정보를 서버에 보내고, 이후에는 세션과 쿠키를 이용해 인증하는 방식입니다.
- 서버에서 세션 정보를 기록한 뒤에 세션을 식별하는 id를 Set-Cookie로 클라이언트에 응답합니다. 이후 클라이언트가 서버에 요청할 때 서버에서 응답한 쿠키를 자동으로 포함하게 됩니다.
- 세션은 일정한 기간이 지나거나 클라이언트에서 로그아웃 요청을 보낼 경우, 해당 세션이나 로그인 유저를 만료 처리합니다.
세션 및 쿠키 기반 인증 과정

1. 인증되지 않은 사용자가 서버에 로그인 계정 정보를 보냅니다.
2. 서버는 전달 받은 계정 정보를 통해 DB 를 조회하고 사용자 확인을 합니다.
3. 서버는 세션 스토리지에 세션을 생성합니다.
4. 서버는 세션 스토리지로 부터 세션 ID 를 발급받습니다.
5. 서버는 클라이언트에게 세션 ID 를 포함해 응답 메시지를 보냅니다. 클라이언트는 전달받은 세션 ID 를 쿠키에 저장합니다.
5. 사용자는 이후 발생하는 요청에 발급 받은 쿠키를 포함해 서버로 보냅니다.
6. 서버는 쿠키를 통해 세션 ID 를 얻은 후 세션 스토리지로부터 세션을 얻습니다.
7. 서버는 얻어진 세션을 바탕으로 요청 데이터를 찾아 사용자에게 응답합니다.
세션 및 쿠키 기반 인증 방식의 장점과 단점
장점
- 세션 ID 는 유의미한 값을 가지고 있지 않아서 HTTP 헤더나 바디에 직접 계정정보를 담아 전송하는 것보다 보안에 좋습니다.
- 세션 ID 는 고유한 값이기 때문에 서버 메모리에서 바로 검색할 수 있어 성능 향상을 기대할 수 있습니다.
단점
- 해커가 동일한 쿠키를 가지고 동일한 요청을 보낼 경우 구분할 수 없습니다. (세션 하이재킹) - 이같은 단점을 보완하기 위해 세션 유효기간을 짧게 설정하고, HTTPS 프로토콜을 사용해야 합니다.
- 세션 스토리지는 별도의 메모리를 사용해서 동시 사용자가 많을수록 서버에 부하가 생길 수 있습니다.
토큰 기반 인증 방식
- 토큰 기반 인증이란 인증 토큰을 사용하는데, 인증 토큰이란 유저에 대한 정보를 암호화한 문자열입니다.
- 특정 콘텐츠에 접근할 수 있게 해주기 때문에 Access token이라고도 합니다. 토큰의 형식은 JWT(JSON Web Token)형식을 많이 사용합니다.
- 유저의 로그인 상태를 저장하고 요청이 올 때마다 저장 및 확인하지 않고도 요청을 보낸 유저를 식별할 수 있습니다. 대신 토큰 자체를 해석해서 사용합니다.
JWT
- 인증에 필요한 정보들을 토큰으로 만든 것입니다.
- 클라이언트는 요청을 보낼 때, HTTP 헤더에 넣어 서버로 보냅니다.
JWT 구조
- JWT 는 Header, Payload, Signature 로 구성됩니다.
- . 으로 구분되어 있습니다.
- 각 부분은 JSON 을 Base64 인코딩하여 표현합니다.
- Header 에는 Signature 를 해싱하기 위한 해싱 알고리즘 정보가 담깁니다.
- typ: 타입, alg: 해싱 알고리즘 종류
- Payload 에는 토큰에서 사용할 정보, 서버에서 보낼 데이터 등이 담깁니다. 클레임이라고 부르는 정보의 조각이 담깁니다. name, value 키 쌍으로 담깁니다.
- Signature 에는 토큰을 인코딩하거나 유효성 검증을 할 때 사용하는 고유한 암호화 코드가 담깁니다. Header, Payload 를 각각 Base64로 인코딩한 값을 합친 후 비밀 키로 해쉬를 합니다. 그 해쉬 값을 Base64로 인코딩하여 생성합니다. 해시 암호화 알고리즘을 이용해여 암호화되어 있습니다. Signature 에서 사용하는 시크릿 키를 모른다면 암호화된 Header, Payload 를 복호화할 수 없습니다.
토큰 기반 인증 과정

1. 사용자가 로그인 계정 정보를 서버로 보냅니다.
2. 서버가 DB 를 조회하여 사용자를 확인합니다.
3. 서버에서 access token (JWT) 를 발급합니다.
4. 발급한 access token 을 클라이언트에 전달합니다. 이때, 응답으로 인증 토큰을 응답의 바디로 넘기기도 하고, Set-Cookie를 하기도 합니다.
5. 클라이언트는 응답으로 받은 access token 을 서버에 요청할 때 Authorization 헤더에 담아 보냅니다.
6. 서버는 access token 을 검증하여 클라이언트를 식별합니다.
7. 서버는 인가된 사용자에 한해 응답 데이터를 보내줍니다.
8. access token 을 갖고 있기만 하고 만료시간이 지나지 않았으면 항상 로그인 상태를 유지할 수 있습니다.
토큰 기반 인증 방식의 장점과 단점
장점
- 세션 쿠키 기반 인증 방식과 다르게 별도 저장소 관리가 필요 없고 검증만 하면 되기 때문에 별도 세션 스토리지가 필요하지 않습니다. 토큰이 필요한 정보를 모두 가지고 있습니다.
- 페이스북, 구글도 토큰 기반으로 서비스를 제공하기 때문에 관련 기능 확장에 용이합니다.
- Signature 부분에 보낸 정보가 포함되어 있어서 중간에 데이터가 조작되어도 서버에서 이를 알 수 있습니다.
- 로그아웃을 하고 싶으면 간단하게 클라이언트에서 직접 저장한 토큰을 삭제해주면 됩니다.
단점
- 토큰의 경우 세션 ID 와 같이 탈취되었을 때 구분할 수 없습니다. 데이터 조작을 방지할 수는 있지만 해당 유저로 가장해서 행동하는 것은 방지할 수 없습니다. 이를 보완하기 위해 토큰 유효기간을 짧게 설정하고 HTTPS 프로토콜을 사용해야 합니다.
- 필요한 정보가 모두 토큰에서 관리되기 때문에 토큰 크기가 커질 수 있습니다. 데이터 트래픽 크기에 영향을 줄 수 있습니다.
효율성
세션 기반 인증을 사용하면 서버는 항상 로그인 세션 정보를 저장하며, 매 리퀘스트의 유저가 누구인지를 이 정보와 비교를 해야 됩니다. 그리고 이걸 하기 위해서는 용량과 시간이 드는데요. 로그인한 유저가 엄청 많거나 특정 시간에 몰리게 되면 서버의 리퀘스트 처리 속도가 느려질 수도 있습니다.
반면 토큰 기반 인증은 어딘가 저장한 데이터와 비교하는 게 아니라 토큰 자체 내용을 해석하기만 하면 되기 때문에 더 효율적으로 작동할 수 있습니다.
유연성
토큰 기반 인증은 세션 기반 인증보다 조금 더 유연하게 사용될 수 있습니다. 토큰을 발행하는 방법이 똑같고, 시크릿 키만 있으면, 발행한 곳과 확인하는 곳이 달라도 된다는 말인데요.
예를 들어 같은 유저 데이터베이스를 사용하는 여러 서비스들이 있고, 이 사이트들이 같은 방식과 키를 사용해서 토큰을 발행한다면, 한 사이트에서 제공한 토큰을 가지고 있으면, 다른 서비스가 그걸 해석해서 유저를 파악할 수 있는 거죠. 요즘은 크고 복잡한 웹 애플리케이션들을 더 작은 내용을 담당하는 작은 부분들로 나눠서 개발하는 경우가 많은데요. 이럴 때 토큰을 사용하는 게 훨씬 더 유연합니다.
RESTful API
세션 정보와 같이 서버가 "상태" 정보를, 예를 들어 유저가 로그인을 했는지 안 했는지 저장하고 있을 때, stateful 하다고 표현하는데요. REST에 부합하기 위해서는 서버가 상태 정보를 저장하지 않는, stateless 한 특성이 있어야 합니다. 서버는 클라이언트에서 보내는 정보만으로 충분히 상태를 파악할 수 있어야 하죠.
이 기준에서 살펴보면 RESTful한 API 서버를 만들고 있다면 세션 기반 인증보다 토큰 기반 인증이 더 어울립니다.
무효화
세션 기반 인증의 장점 중 하나는 바로 서버에서 세션 데이터를 따로 관리하기 때문에 특정 세션을 손쉽게 무효화할 수 있다는 점입니다. 그냥 세션을 관리하는 테이블에 가서 상태를 만료로 바꾸거나 만료일을 지금 당장으로 해버리면 되겠죠? 하지만 토큰 기반 인증을 사용하면 따로 서버가 상태 정보를 저장하지 않기 때문에 특정 토큰을 무효화하는 게 더 복잡합니다. 그리고 이건 꽤 큰 문제들로 이어질 수 있는데요. 예를 들어 금융 서비스에서 누군가 유저 세션을 가로챘는데 이걸 바로 무효화할 수 없다면 저금한 돈을 뺏기는 문제가 생길 수도 있죠. 물론 이중 비밀번호나, OTP라든지 이걸 방지하기 위한 방법들이 있지만, 세션 기반 인증을 사용하면 한 가지 안전장치를 더 쉽게 사용할 수 있습니다.