(Server) Authorization Header / Bearer & jwt

호두파파·2021년 11월 4일
0

Node.js

목록 보기
24/25
post-custom-banner

프로젝트를 진행하면서 로컬 로그인과 소셜 로그인을 구현해보았다. 소셜로그인은 oAuth2.0 방식을 사용해 구현했으나, 서버로부터 인증키(Access_token)을 받고, 서버로 토큰을 전달하는 방식 등이 메소드로 쉽게 구현되어 있어 어렵지 않게 구현할 수 있었다.

로컬 로그인을 구현함에 있어, Bearer를 사용하는가, jwt를 사용하는가에 대한 방향을 구체화하고자 이 글을 작성한다.

기본 지식


HTTP 인증

HTTP는 엑세스 제어와 인증을 위한 프레임워크를 제공한다. 서버에서 클라이언트 요청을 첼린지 하고, 클라이언트가 인증 정보를 제공하는데 사용될 수 있다.

  • Client가 server로 인증되지 않은 request를 보낸다.
  • Server는 Client로 적어도 하나의 Challenge를 포함하는 WWW-Authenticate응답 헤더와 함께 401(Unauthorized)응답을 보낸다.
    - WWW-Authenticate: 인증 타입에 대한 정보를 제공하는 HTTP Header
  • Client는 Authorization요청 헤더에 인증정보(Credentials)를 포함해 재요청을 보낸다.
  • Server에서 인증정보를 확인해 올바른 청보라면 200(OK),아니라면 400(Forbidden) 응답을 보낸다.

Authorization Header

HTTPAuthorization request header. Server의 사용자 에이전트임을 증명하는 자격(Credentials)을 포함해, 서버에서 WWW-Authenticate응답 헤더와 함께 401(Unauthorized) 응답을 보낸 뒤 추가한다.

Authorization: <type> <credentials>

type

인증타입(인증 scheme라고도 불림). 보통 타입은 Basic이며, type에 따라 credentials가 변경된다.

credentials

인증정보. 만약 Basic 인증타입이 사용되었다면, credentials는 다음과 같이 만들어진다.

  • 사용자명과 비밀번호가 콜론을 이용해 합쳐진다.
  • 그 결과에 대한 문자열을 Base64로 인코딩한다.
    - Base64 인코딩은 암호화나 해싱을 의미하지 않기 때문에, Basic 인증 타입을 쓰는 경우 HTTPS 접속을 권장한다.

사용자가 로그인을 했을때, 서버는 그 사용자를 나타내는 특별한 값을 만들어서 전달해 권한을 부여하고, 사용자는 나중에 Authorizatin 헤더로 그 인증 데이터를 보내준다

'사용자를 나타내는 값'을 어떻게 만들어낼 지는 표준이 결정해준다 표준을 따르지 않는다면, 인증 스키마에 대한 의사결정을 진행해야 한다.

선택지

표준 상 Authorization 헤더의 값에는 RFC에 의해 표준화된 인증 스키마를 사용할 수 있게 되어 있다.

  • Basic
  • Oauth 2.0을 사용하는 Bearer
  • [비표준] JWT, 또는 JWT를 사용하는 BEARER

Bearer & jwt

Bearer

credential에 oAuth2.0으로부터 획득한 access_token을 넣는 타입이다. oAuth는 Client가 리소스 소유자(사용자)를 대신해 보호된 리소스에 접근할 수 있는 방법을 제공한다.

일반적으로 access_token을 발급해주고, 이를 통해 리소스 서버에 대신 접근할 수 있다.

jwt

jwt라는 타입은 존재하지 않는다. jwt(json web token)에 대해 명시적으로 타입이 정해지지 않아 jwt를 타입으로 사용하는 경우가 있다(고 추정)

위 Bearer 정의를 따르면, bearer token으로 jwt를 사용하는 것은 크게 문제가 되지 않는다.

대부분 개발자들이 bearer token으로 jwt를 사용하는 것을 많이 볼 수 있다. 왜 그럴까?


  • Basic은 ID와 비밀번호를 base64 인코딩하는 방식이다. base64는 별도의 key 없이도 복호화가 가능한 인코딩이므로, 안전하지 않다.
  • Bearer에서 사용하는 OAuth2.0방식의 인증은 확장성이 매우 높다. 'Facebook 계정으로 로그인'과 같은 기능이 oAuth로 구현되었다. OAuth2.0은 자체 암호화를 지원하지 않기 때문에 HTTPS를 쓰는 것을 권고하고 있다. 더불어 스펙 자체에서 명확하게 정의하지 않은 부분이 꽤 있어 고민이 깊어진다.
  • Bearer에 JWT를 사용하거나, JWT라는 타입을 쓰는 것도 표준이 아니다 그러나 HTTPS 문제로 OAuth2.0을 보류하게 되니, 대신 쓸 토큰 기반 인증 시스템으로 JWT가 가장 선호된다.

보호된 리소스에 대한 접근 권한을 부여하기 위해 제시하는 유일한 작업이 토큰을 전달하는 것 이라는 관점에서 볼때 이 토큰을 bearer token이라고 부를 수 있다. 따라서 JWT를 사용하는 인증 방식도 사실상 bearer라는 문맥에서 벗어나지 않으며, 단지 bearer token을 생성하지 않기 위해 OAuth2.0 관련 사양을 사용하지 않는 것일 뿐, Authorization 헤더를 사용하고, 디지털 방식으로 서명(sign)된 토큰을 사용한다면, JWT를 사용하는 것은 큰 문제가 되지 않는다.


참조

백엔드가 이정도는 해줘야 함 - 5. 사용자 인증 방식 결정

profile
안녕하세요 주니어 프론트엔드 개발자 양윤성입니다.
post-custom-banner

0개의 댓글