로그인 인증 - Basic, Token, JWT

SeungTaek·2022년 2월 20일
0

Computer Science

목록 보기
3/3
post-thumbnail
post-custom-banner

로그인 인증 방법

1. Basic 인증

모든 HTTP 요청에 아이디와 비밀번호를 같이 보내서 인증하는 방식이다.
최초 로그인한 후 HTTP 요청 헤더의 Authorization 부분에 Basic <ID>:<Password> 처럼 아이디와 비밀번호를 콜론으로 이어붙인 후 Base64로 인코딩한 문자열을 함께 보낸다.
이 요청을 수신한 서버는 인코딩된 문자열을 디코딩해 아이디와 비밀번호를 찾아낸 후 사용자 정보가 저장된 데이터베이스 또는 인증 서버의 레코드와 비교한다. 비교결과 아이디와 비밀번호가 일치하면 요청받은 일을 수행, 아니면 거부한다.

요청 헤더 예시

Authorization: Basic aGvsbG93b3JsZeBnbWFpbC5jb206MTIzNA==

단점

  1. 아이디와 비밀번호를 노출하게 된다.
    • 인코딩은 보안을 목적으로 하는게 아니다. 디코더만 있다며 누구나 아이디와 비밀번호를 확인할 수 있다.
    • 누군가 HTTP 요청을 가로채는 것을 MITM(Man in the Middle Attack) 이라 한다.
    • 따라서 반드시 HTTPS와 사용해야 한다.
  2. 사용자를 로그아웃시킬 수 없다.
    • 모든 요청이 일종의 로그인 요청이기 때문이다.
  3. 사용자의 계정 정보가 있는 저장 장소(인증 서버나 DB)에 과부하가 걸릴 확률이 높다.
    • 1초에 10만 개를 처리하는 서버가 있다 가정하자.
    • 10만 개의 요청을 확인하려면 10만 번 계정 정보의 저장 장소를 갔다 와야한다.



2. 토큰 기반 인증

  • 토큰(Token)은 사용자를 구별할 수 있는 문자열이다. 대표적으로 Bearer Token이 있다.
  • 토큰은 최초 로그인 시 서버가 만들어 준다. 서버가 자신만의 노하우로 토큰을 만들어 반환하면 클라이언트는 이후 요청에 아이디와 비밀번호 대신 토큰을 계속 넘겨 자신이 인증된 사용자임을 알리는 것이다.
  • 사실 토큰은 세션 기반 인증과 별 다른게 없다. 이름만 바뀐 세션일 뿐이다.
  • 토큰 이용만으로는 스케일 문제를 해결할 수 없다.



3. JSON 웹 토큰

  • 전자 서명(Digital Signature) 된 토큰을 이용해 스케일 문제를 해결할 수 있다.
  • JWT도 토큰 기반 인증이므로 서버가 생성하지만, 전자 서명을 한다는 점이 다르다.
  • JWT 토큰은 {header}.{payload},{signature}로 구성돼 있다.
  • JWT의 예는 다음과 같다. : Authorization: Bearer eyKhbGci0iJIUzUxMiJ9.eyasdkfajsdlkfasdfklja.sdflaskdjf;lasdfjkalsdf
  • 인코딩된 토큰을 Base64로 디코딩하면 아래와 같다.
{ // header
  "typ": "JWT",
  "alg"L "HS512"
},
{ // payload
  "sub":"4028809378739d3891839a89481883c13",
  "iss": "demo app",
  "iat": 1595733657,
  "exp": 1596597657
}. //signature
Nn4dasdfasdjhfsdfasdfjD3fDFHHeufsiefh3f98742fJHFKEH13usdhfw

각 파트의 필드

  • Header
    • typ: Type을 줄인 말로 토큰의 타입을 의미한다.
    • alg : Algorithm을 줄인 말로 토큰의 서명을 발행하는 데 사용된 해시 알고리즘의 종류를 의미한다.
  • Payload
    • sub: Subject를 줄인 말로 토큰의 주인을 의미한다. sub는 ID 처럼 유일한 식별자여야 한다.
    • iss: Issuer를 줄인 말로 토큰을 발행한 주체를 의미한다.
    • iat: issued at을 줄인 말로 토큰이 발행된 날짜와 시간을 의미한다.
    • exp: expiration을 줄인 말로 토큰이 만료되는 시간을 의미한다.
  • Signature
    • 토큰을 발행한 주체 Issuer가 발행한 서명으로 토큰의 유효성 검사에 사용된다.

전자 서명

  • JWT에서 전자 서명이란 {헤더}.{페이로드}와 시크릿키를 이용해 해시 함수에 돌린 암호화한 결과 값이다.
  • 시크릿키는 나만 알고 있는 문자열, 비밀번호 같은 것이다. 너무 간단하지만 않으면 아무거나 상관없다.

로그인 과정

  1. 서버는 사용자의 아이디와 비밀번호를 서버에 저장된 아이디와 비밀번호에 비교화 인증한다.
  2. 만약 인증된 사용자인 경우 사용자의 정보를 이용해 {헤더}.{페이로드} 부분을 작성하고 자신의 시크릿키로 {헤더}.{페이로드} 부분을 전자 서명한다.
  3. 전자 서명의 결과로 나온 값을 {헤더}.{페이로드}.{서명}으로 이어붙이고 Base64로 인코딩한 후 반환한다.

인증 과정

  1. 누군가 이 토큰으로 리소스 접근을 요청한다.
  2. 서버는 이 토큰을 Base64로 디코딩 후 얻은 JSON을 {헤더}.{페이로드}와 {서명} 부분으로 나눈다.
  3. 서버는 {헤더}.{페이로드}와 자신이 갖고 있는 Secret 으로 전자 서명을 만든 후 방금 만든 전자 서명과 요청으로 들어온 {서명}부분을 비교해 유효성을 검사한다.

단점

누군가 토큰을 훔쳐가면 어떻게 될까? 해당 계정의 리소스에 접근할 수 있게 된다. 그렇기에 반드시 HTTPS를 통해 통신해야 한다.



Reference

React.js, 스프링부트, AWS로 배우는 웹 개발 101 (에이콘, 김다정)

profile
I Think So!
post-custom-banner

0개의 댓글