토큰 기반 인증 Bearer Authentication

OAuth를 들어가려고 생각하다가, 이전에 Bearer scheme 부터 조져야 겠다는 생각을 먼저 해봤다

블로그에 글을 쓸 때 마다 드는 생각

Bearer scheme 에 대해서 정확히 설명을 하기 위해서 여러 자료들을 봤는데, 한글 풀이형으로 가장 알맞은 말은 전달자 가 제일 그나마 알맞은 말인 것 같다. 그래서 제목에 전달자 인증 이라고 쓰려고 보니 또 전달감이 별로기에... (응???)
내 개인적인 생각에 이 단어는, 단어 그대로 베어러 로 익히는게 좋다 (영어 그대로 익히는게 학습할 때는 더 좋은 효과를 낸다)

bearer. noun. bear·​er | \ ˈbar-ər \
someone or something that bears, supports, or carries
She was the bearer of bad news. (그녀는 나쁜 소식의 전달자였습니다.)

그렇다면 우리는 여기서 왜? 도대체 Bearer 라는 단어을 쓰게 되었을까?? 에 대한 의문을 갖도록 해야 한다. 도대체 저 단어는 어디서 나온 것이지? 는  (➝ RFC 6750) 를 확인하면 되지만, 이럴꺼면 블로그에 글도 쓰지도 않는다!!


자! 그럼 이번에도 썰을 풀어 보도록 한다
썰은 썰일 뿐, 믿지는 말자.  RFC 문서를 믿도록 하자

세션 기반 인증에서 토큰 기반 인증으로 넘어가는 과도기에는 정말 많은 무수히 많은 이라 말하고 자기들 멋대로 사용하는 Scheme들이 존재했었다. 대충 이런 식이다
Authorization: <type> <credentials>

ex1) Authorization : apikey xH3m-H/jGnv5
ex2) Authorization : Token AKV1...token.value...UEFJ
어? 너희 회사두???
일단 Scheme을  Apikey, Token, myCompanyNameToken, memberToken, 내마음속이름토큰 등등
개발자가 마음대로 개발해서 정하는 Scheme 이름이 곧 개발하는 서비스에서 사용하는 토큰 기반 인증 방식의 Scheme가 되었다
사실 서비스 개발의 입장에서 본다면 Scheme 라는게 무엇이던간에, Token 이라는 값이 제대로 서버와 클라이언트에 전달 되고, 해당 토큰으로 인증(Authentication)과 인가(Authorization)가 잘 작동되기만 한다면 인증 서비스라고 생각할 수'는' 있다

그러나 이 방식은 다른 써드 파티 - 이후에 나올 OAuth, OIDC 같은 공개 표준 규약 open standard protocol - 에서 사용하려면 토큰 인증 형태가 다르기 때문에 다시 로그인을 해야 하는 형태가 될 수 밖에 없었다

그래서 W3C는 이 형태가 표준이 없다고 생각하고, 토큰 기반 인증에 대해서 표준 내용을 제정하게 되었고, 토큰 기반 인증이라면 Bearer 라는 Scheme 을 사용하도록 표준 문서로 제시한 내용이다  (➝ RFC 6750)

어떤가유? 그럴싸하쥬?


이 글에서는 Bearer 라는 <type>이 규칙(protocol)의 일부가 된 것을 설명하는 것이고, 해당 <type>이 다를 경우 전혀 문제가 되지는 않는다는 점을 알리고 싶었다

Bearer Authentication 이라는 방식이 어떻게 해서 생겨났고, 그것을 사용해서 개발하는 사람들이 제대로 이해하기를 바란다

다음 설명은 Bearer 이후에 붙는 Token 에 대한 이야기이다

Authorization: <type> <credentials>  <credentials> 자리에는 token 이 들어가야 하는 자리다

대부분의 개발자는 Bearer 가 오면 그 뒤에 JWT (JSON Web Token) 이 오는 것으로 잘 알고 있다. 아니 거의 맹목적으로 Bearer 는 JWT  정도로 믿고 있을꺼라 믿어 의심치 않는다

하지만 아래와 같이 Amazon AWS와 같은 호스트 서비스에 의해 제공되는 다른 Scheme도 존재한다

Authorization: AWS4-HMAC-SHA256 
Credential=AKIAIOSFODNN7EXAMPLE/20130524/us-east-1/s3/aws4_request, 
SignedHeaders=host;range;x-amz-date,
Signature=fe5f80f77d5fa3beca038a248ff027d0445342fe2855ddc963176630326f1024

<type> scheme 는 AWS-HMAC-SHA256 이고, <credentials>는  , 로 분리하고 key=value로 된 쌍(pair)이 3개가 있는 값이다. 그리고 각 키의 특징은 모두 다른 값의 형태로 존재하는 것을 볼 수 있다

보통 이렇게 나오면 아래 질문들이 나올 것 같아서 정리해 보았다

Q : <type>이 Bearer 가 아니기 때문에 저런 형태가 들어갈 수 있는 것 아닌가?
A : 위에도 말했듯이 AWS 에서 개발해서 정하는 Scheme 이름이 곧 개발하는 서비스에서 사용하는 토큰 기반 인증 방식의 Scheme가 되었다. AWS 자체 Scheme 이라 Value(credential)를 AWS의 방식으로 나타내는게 가능하다

Q : <type>이 Bearer 면 JWT가 들어가야 하는 것 아닌가?
A : JWT 도 Token 형태의 하나이지만, 굳이 JWT 가 아니더라도 다른 토큰이라도 가능하다. Bearer 뜻 자체가 전달자 이니,  전달자 토큰 (Bearer Token)이면 가능한 표현이다 Bearer jn3WS8VnjdKxTZ92X 이런 형태의 토큰이라도 가능한 표현이긴 하다

Q : 그렇다면 Bearer (일반적인) <Token> 과 JWT 를 사용함에 다른 점은?
A :

<Token>

  • JWT가 나오기 이전에는 <Token>은 본질적으로 의미가 없는 문자열의 조합이었다
  • 해당 <Token>을 DB조회를 하여 맞는 권한 Claims 을 가져오는 방식으로 개발을 했었다
  • <Token>을 사용할 때마다 DB 혹은 그에 알맞는 저장소 (Persistence layer) 가 필요하다는  것이다

JWT

  • JWT는 자체적으로 Claims를 인코딩하고 서명(signing)을 통해 확인 (verify) 할 수 있다
  • 상태를 저장하지 않음 (stateless) 으로 DB 혹은 저장소 (Persistence Layer)가 필요 없다는 소리다
  • JWT만으로도 많은 것들을 확인 가능하여, 해당 Application 에서 인증 관련 프로세스의 간소화가 가능하다 (DB 로드가 줄어들기 때문에)
  • JWT를 발행(publish)하는 서비스만 refresh token 발행으로 인한 DB/Persistence Layer 에 대한 대비를 할 필요가 있다 (refresh token 저장은 해야하니)

Bearer Authentication 을 설명하려고 하는데 JWT는 당연히 김치 같은 필수 밥 반찬이기에 어쩔 수 없이 설명을 꺼넸지만, 정확히 이해하면 좋겠다

참! 정말 1g 정도의 팁(Tip)을 알려준다 API Endpoint 를 사용할 때 HTTP Header 에 Authroization 을 넣고 Bearer 가 아닌 bearer 로 넣었을 때 서버마다 다르지만, 정확히 작동 안하는 서버도 있음을 인지하고 Bearer 로 정확히 대소문자 구별해서 넣기를 바란다

Authorization : Bearer xxxx   (O)
// 대소문자 구별을 하는 Bearer
Authorization : bearer xxxx   (X)

References

HTTP 인증 - HTTP | MDN
HTTP는 액세스 제어와 인증을 위한 프레임워크를 제공합니다. 가장 일반적인 인증 방식은 “Basic” 인증 방식입니다. 이 페이지에서는 일반적인 HTTP 인증 프레임워크를 소개하고 서버에 HTTP의 Basic 인증 방식으로 접근을 제한하는 것을 보여 줍니다.
rfc6750
The OAuth 2.0 Authorization Framework: Bearer Token Usage (RFC )
Authenticating Requests: Using the Authorization Header (AWS Signature Version 4) - Amazon Simple Storage Service
Use the HTTP authorization header to provide authentication of the request.
What’s the difference between JWTs and Bearer Token?
I’m learning something about Authorization like Basic, Digest, OAuth2.0, JWTs, and Bearer Token. Now I have a question. You know the JWTs is being used as an Access_Token in the OAuth2.0 standard.