Token 에서의 Bearer?

2ch·2024년 12월 2일
post-thumbnail

들어가기에 앞서

현재 iOS 앱 유지보수 및 새로운 기능 추가를 하면서 코드를 보던 중, token 부분에서 bearer라는 키워드를 발견할 수 있었다. 사실 해당 프로젝트 이전에도 웹 프로젝트를 진행하면서, 처음에는 명세대로 쿠키-세션을 적용하였으나, 프로젝트 마지막에 다른 팀원이 혼자서 jwt를 적용하여 수정했다. 이로인해 인증에 대한 지식 및 이해가 부족했다. Bearer에 대한 궁금증을 해결하면서 인증 및 인가와 관련된 부분에 대해서 정리하고자 한다.

HTTP

HTTP란 서버와 클라이언트 간에 정보를 전송하도록 설계된 프로토콜이다. 클라이언트가 요청을 전송하고, 서버는 이에 대한 응답을 해당 클라이언트에게 전달한다. 전달을 마친 서버는 클라이언트와의 연결을 종료하는데, 이를 비연결성이라고 한다. 이렇게 연결을 끊은 서버는 클라이언트에 대한 정보를 유지하지 못하게 되고, 이를 stateless라고 한다. 이러한 특성 때문에 Cookie와 Session이 등장하게 된다.

Cookie란? (MDN)
HTTP 쿠키(웹 쿠키, 브라우저 쿠키)는 서버가 사용자의 웹 브라우저에 전송하는 작은 데이터 조각입니다. 브라우저는 그 데이터 조각들을 저장해 놓았다가, 동일한 서버에 재 요청 시 저장된 데이터를 함께 전송합니다. 쿠키는 두 요청이 동일한 브라우저에서 들어왔는지 아닌지를 판단할 때 주로 사용합니다. 이를 이용하면 사용자의 로그인 상태를 유지할 수 있습니다. 상태가 없는(stateless) HTTP 프로토콜에서 상태 정보를 기억시켜주기 때문입니다.

서버는 클라이언트 측에서 저장하고 싶은 정보에 대해 헤더의 Set-Cookie에 담아서 보내고, 클라이언트는 이를 저장 후, 서버에게 요청을 보낼 때마다 헤더의 Cookie에 담아서 보낸다. 이를 통해 서버 측에서는 어떤 클라이언트인지 식별이 가능한 것이다.

허나, 쿠키는 여러가지 문제점이 있는데, 가장 대표적인 보안 문제에 대해서만 다루자면 요청 시 쿠키의 값 그대로, 즉 raw value를 전송한다는 문제점이 있다. 또한, 아무래도 유출 및 조작이 용이하다.

Session

Cookie는 이런저런 인가에 필요한 정보들이 노출된 상태로 전송되기 때문에 위험했다. 세션의 경우에는 이러한 정보들에 대해서 서버 측에서 저장하고 관리하기 때문에, 세션 아이디를 쿠키에 담아서 전송한다. 쉽게 말하자면, 쿠키에 민감한 정보들을 모두 빼고(서버에 저장되어있음.) 세션 아이디만 담는 것이다.

이러한 특성 때문에 쿠키와는 다르게 쿠키를 포함한 패킷이 노출되더라도 개인정보가 직접적으로 노출되는 일은 없다. 허나, 세션 아이디를 탈취하여 클라이언트인척 할 수 있다는 문제가 있다. 아마 이것을 예전에 보안 공부할 때 세션 하이재킹이라고 했던 것 같다.

JWT

JWT란 인증에 필요한 일련의 정보들을 암호화시킨 토큰이다. 토큰 역시 헤더에 토큰을 담는다. 토큰은 쿠키와 세션의 단점을 보완하기위해 만들어졌다. 사용자 정보를 노출하는 쿠키의 단점, 서버에 공간을 요구하는 세션의 단점을 해결했다.

먼저, JWT 구조에 대해서 알아보자. JWT 는 '.' 을 separator로 3개의 문자열로 나뉜다. Form은 다음과 같다.

(Header) . (Payload) . (Signature)

Header에서는 해싱 알고리즘을 나타내는 alg와 토큰의 타입을 나타내는 typ라는 키가 존재한다.
Payload에서는 클라이언트의 ID 및 유저 이름, 유효 기간 등이 포함된 정보가 존재한다. 이 포스트에서는 디테일하게 다루지 않을 내용이지만, Payload에 담는 정보의 한 조각을 claim이라고 하고, 세 가지 분류가 있다고 한다.
Signature에서는 encode된 Header와 Payload를 더한 뒤 Private key로 해싱하여 사용한다.

일부의 장단점만 다뤄보자. 이러한 토큰은, signature field가 존재하기 때문에 데이터 변조를 예방할 수 있다. (보안 공부했던 기억으로 이걸 무결성이라고 했던 것 같은데, 잘못되었다면 댓글 부탁드립니다!) 또한, 아무래도 별도의 디폴트 쿠키 저장소가 존재하지 않는 앱에서 동작한다는 것이 내가 이 포스트를 작성하는 이유의 근본적인 원인이지 않을까 싶다. 가장 대표적인 단점으로 토큰을 탈취당할 경우, 토큰이 한번 발급되었을 때 해당 토큰이 만료될 때까지 접근이 가능하고 접속에 대한 제한이 힘들다는 것이다.

Bearer

결국 내가 알고싶었던 것은 단순히 내가 현재 담당하고 있는 앱에서의 Authorization에서 token앞에 bearer가 붙는게 과연 무엇을 의미하는 것인가였다.

결론부터 말하자면, 토스 페이먼츠 용어사전을 참고했을 때, Bearer 인증 방식은 OAuth 2.0 프레임워크에서 사용하는 토큰 인증 방식이라고 한다.

더 나아가 위 이미지는 포스트에서 Auth Type을 선택하는 화면인데, 저기에 Learn more about Bearer Token 버튼을 눌렀을 때 다음과 같이 말한다.

Bearer tokens enable requests to authenticate using an access key, such as a JSON Web Token (JWT). The token is a text string, included in the request header. In the request Authorization tab, select Bearer Token from the Auth Type dropdown list. In the Token field, enter your API key value. For added security, store it in a variable and reference the variable by name.

Authorization 필드에는 다음과 같은 format이 존재한다.

Authorization: <type> <credentials>

bearer는 type에 속한 것이며, Basic, Digest 등 다른 타입들이 존재한다고 한다.

마무리

지금까지 HTTP에 거쳐 bearer token까지 아주 간략하게 알아봤다. bearer가 무슨 의의를 가지는지를 알아보기 위해서 시작했던 포스트였기 때문에 각 내용에 대해서 아주 디테일하게 다루지는 못했지만, 이 기회로 모르고 넘어갔던 내용들, 애매하게 알고 있던 개념들을 조금은 잡은 것 같다.

여담이지만 토스페이먼츠 용어사전이 있다는 것은 이번에 처음 알았는데, 정말 유용한 것 같다. 앞으로도 정의가 헷갈리거나 바로 생각이 나지 않는 경우 종종 써야겠다.

profile
Seoul Hongik Univ ce & 42 Seoul Member

0개의 댓글