본문 바로가기
Work/개발 노트

[WEB] 토큰 기반 인증

by ★용호★ 2020. 9. 4.
이 글에서는 토큰 기반 인증에 대한 여러 글들을 조사하여 정리하였습니다. 참조한 레퍼런스는 하단에 링크 첨부하였습니다.

서버 기반 인증의 문제점

  • 세션을 서버 메모리에 저장할 경우 사용자가 해당 서버로 접속해야만 세션이 유지됨
  • 별도DB에 저장 할 경우 모든 웹 서버가 세션 DB에 의존성이 생김
  • 세션 관리를 위해 쿠키가 많이 사용되는데 쿠키는 단일 도메인 또는 서브도메인에서만 작동하도록 설계 되어 있음 (CORS 문제). 즉, 쿠키 사용시 CORS 설정을 해야하기 때문에 도메인 분리가 번거러움

토큰 인증 방법

  • 토큰에는 서버에서 정상적으로 발급된 토큰임을 증명하는 signature를 포함하고 있음
  • 클라이언트에서는 토큰을 받급 받은 후 매 요청마다 토큰을 함께 서버에 전달
    • 서버 전달 시 HTTP Header에 토큰을 포함
  • 서버에서 토큰 검증이 성공해야만 응답을 받을 수 있음

토큰 사용 시 장점

  • 토큰 정보를 클라이언트에 저장하기 때문에 의존성이 없다 (Stateless)
  • 세션 정보를 저장하지 않기 때문에 확장이 자유롭다 (Scalability)
  • 다른 서비스에 권한을 공유할 수 있다 (Extensibility)
  • 토큰만 유효하다면 디바이스나 도메인에 상관없이 어디서나 정상적으로 처리할 수 있다. (CORS 해결)
    • 서버에서 Response 시 "Access-Control-Allow-Origin: *" 헤더값을 포함하여 CORS 허용

 

JWT (JSON Web Token)

  • 위에서 설명한 토큰 인증 방법 중 가장 많이 사용되고, 웹 표준
  • JWT 토큰 발급 시 라이브러리를 사용하면 알아서 인코딩 및 해싱 작업을 해줌
    • 인코딩 시에는 base64로 인코딩이 되는데 인코딩 시 뒤에 '=' 문자가 붙게됨
    • 이는 base64의 padding 문자이고, 없어도 디코딩 시 문제되지 않음
    • URL 파라미터로 base64가 전달 될 경우 url-safe하지 않기 때문에 제거되어야함
    • JWT 토큰 발급 시에는 이 padding 값이 제거되어서 반환됨

포함되는 정보

  • 토큰에 대한 기본 정보
  • 클라이언트에 전달 할 사용자 정의 정보 (payload)
  • 토큰이 검증되었음을 증명해주는 값 (signature)

전달 방법

  • HTTP 헤더에 넣거나, URL의 파라미터로 전달
    • 웹 서버는 대부분 HTTP 헤더에 포함

사용 예

  • 회원 인증
    1. 사용자 로그인
    2. 서버에서 사용자 정보에 기반한 JWT 발급
    3. 사용자가 서버에 요청할 때마다 JWT를 포함하여 전달
    4. 서버에서는 요청을 받을 때마다 signature가 유효한지 검증하고, payload로 권한 확인
  • 정보 교류
    • 정보가 sign 되어 있기 때문에 정보를 보낸 사용자가 변경되지 않았는지, 정보가 조작되지 않았는지 검증

JWT 사용 방법

  • JWT는 dot(.)을 구분자로하여 Header, Payload, Signature를 포함해야 함
  • Header에는 토큰의 타입과 해싱 알고리즘을 지정
      {
        "typ": "JWT",
        "alg": "HS256"
      }
    • 위 값을 base64로 인코딩
  • Payload에는 토큰에 담을 정보를 포함
    • 정보의 단위를 클레임(claim)이라고 하고, 3가지 유형이 있음. 모두 key-value 형식으로 지정
      • registered claim : 미리 등록되어 있는 유형을 의미
      • public claim : 충돌 방지를 위해 키를 URI 형식을 사용
      • private claim : 클라이언트/서버 간의 협의 하에 사용되는 사용자정의 데이터
    • 아래와 같이 claim을 혼합하여 Play로드를 생성
        {
            "iss": "yonghochoi.com",
            "https://yonghochoi.com/jwt": true,
            "username": "yonghochoi"
        }
      • 위 값을 base64로 인코딩
  • Signature에는 Header의 base64 인코딩 값과 Payload의 base64 인코딩 값을 dot(.)을 구분자로 하여 합친 후에 비밀키를 사용하여 해쉬값을 생성
    • 이 때 해쉬 생성에는 앞서 지정한 해쉬 알고리즘이 사용됨
    • 해시 값 또한 base 64로 인코딩
  • Header, Payload, Signature 각각의 Base64 인코딩 값을 dot(.)을 구분자로 합치면 하나의 JWT 토큰이 완성됨
  • 완성된 JWT 토큰은 아래 JWT Debugger 사이트를 사용하여 검증 테스트를 해볼 수 있음

참고

 

#3 Golang JWT 토큰으로 인증 구현하기

요즘 백엔드, api 서버의 인증 방식의 대세는 단연코 JWT 토큰인 것 같습니다. session 방식의 인증은 다수의 사용자의 모든 session 정보를 메모리에 가지고 있어야 하기 때문에 리소스 소모가 많고, �

bourbonkk.tistory.com

 

Implementing JWT based authentication in Golang 🔐

A tutorial on building a web application in Go that uses JWT (JSON web token) based authentication

www.sohamkamani.com

 

[JWT] JSON Web Token 소개 및 구조 | VELOPERT.LOG

지난 포스트에서는 토큰 기반 인증 시스템의 기본적인 개념에 대하여 알아보았습니다. 이 포스트를 읽기 전에, 토큰 기반 인증 시스템에 대해서 잘 모르시는 분들은 지난 포스트를 꼭 읽어주세�

velopert.com

 

댓글