인증방식

서버 기반 인증 방식

https://images.velog.io/images/djaxornwkd12/post/4cbe021c-e4e3-4f59-97fe-941f7317078f/image.png

  • 서버 기반 인증 방식은 서버측에서 유저 정보를 저장 => 세션
  • 유저가 로그인을 하면 세션을 만들고 서버의 메모리와 데이터베이스에 저장 문제
  • 사용자 수가 늘어날수록 세션으로 저장하는 정보가 증가하기에 메모리를 많이 사용
  • 쿠키는 단일 도메인 및 서브 도메인에서만 작동하기 때문에 여러 도메인에서 관리가 번거롭다
  • 웹 어플리케이션에서 세션을 관리 할 때 자주 사용되는 쿠키는 단일 도메인 및 서브 도메인에서만 작동하도록 설계되어 있음, 여러 도메인에서 관리가 번거롭다 (CORS)

토큰 기반 인증 방식

https://velopert.com/wp-content/uploads/2016/12/token-diagram.png

  • 인증받은 사용자들에게 토큰을 발급하고, 서버에 요청을 할 때 헤더에 토큰을 함께 보내도록 하여 유효성 검사

장점

  • 무상태성(Stateless) & 확장성(Scalability) 토큰은 클라이언트 측에 저장되기 때문에 서버는 완전히 Stateless하며, 클라이언트와 서버의 연결고리가 없기 때문에 확장하기에 매우 적합하다. 만약 사용자 정보가 서버 측 세션에 저장된 경우에 서버를 확장하여 분산처리 한다면, 해당 사용자는 처음 로그인 했었던 서버에만 요청을 받도록 설정을 해주어야 한다. 하지만 토큰을 사용한다면 어떠한 서버로 요청이 와도 상관이 없다.

stateless vs stateful

  • 상태를 서버에서 저장하고 있다는 의미
  • stateless : 서버에서 상태 저장 X
  • stateful : 서버에서 상태 저장

  • 보안성 클라이언트가 서버로 요청을 보낼 때 더 이상 쿠키를 전달하지 않으므로, 쿠키 사용에 의한 취약점이 사라지게 된다. 하지만 토큰 환경의 취약점이 존재할 수 있으므로 이에 대비해야 한다.

  • 확장성(Extensibility) 토큰 기반의 인증 시스템에서는 토큰에 선택적인 권한만 부여하여 발급할 수 있으며 OAuth의 경우 Facebook, Google 등과 같은 소셜 계정을 이용하여 다른 웹서비스에서도 로그인을 할 수 있다.

  • 여러 플랫폼 및 도메인 서버 기반 인증 시스템의 문제점 중 하나인 CORS를 해결할 수 있는데, 애플리케이션과 서비스의 규모가 커지면 여러 디바이스를 호환시키고 더 많은 종류의 서비스를 제공하게 된다. 토큰을 사용한다면 어떤 디바이스, 어떤 도메인에서도 토큰의 유효성 검사를 진행한 후에 요청을 처리할 수 있다. 이런 구조를 통해 assests 파일(Image, html, css, js 등)은 모두 CDN에서 제공하고, 서버 측에서는 API만 다루도록 설게할 수 있다.

JWT 가 필요한 이유

JWT = 토큰 기반 인증 방식
HTTP 는

  • Connenctionless : 클라이언트가 요청을 서버에게 보내면 서버는 이에 대한 적절한 응답을 한 후에 연결을 종료합니다.
  • Stateless : Connenctionless의 특징으로 서버와 클라이언트와의 연결이 종료된다면 상태 정보는 저장하지 않고 사라집니다. 위 특징을 가지고 있기 때문에 로그인 후 사용자가 새로운 요청을 했을 때 과거에 로그인 한 사실을 기억하지 못한다
    => 로그인 시 사용자에 따른 토큰을 가지고 있고 구입을 하거나 사이트를 이용할 때 이 토큰을 함께 요청 ,
    토큰엔 요청한 사람의 정보가 담겨있기 때문에 DB를 조회하지 않고 누가 요청하는지 알 수 있다

JWT (Json Web Token) 란 ?

https://jwt.io/ JSON 객체를 사용하여 가볍고 자가수용적인 (self-contained) 방식으로 정보를 안전성 있게 전달해주기 위한 토큰

JWT 구성

https://media.vlpt.us/images/geunwoobaek/post/dd0c8156-1ea6-4c95-bcd8-fbb715768e63/image.png .을 구분자로 3가지 문자열로 구성되어 있음

https://user-images.githubusercontent.com/39696812/122652589-8e62ff80-d17a-11eb-94f5-fc2df6284369.png

  • 해싱 알고리즘 : alg
  • 토큰 제목 : admin
  • exp : 토큰 만료 시간

Header : Signature 를 해싱하기 위한 알고리즘 정보

  • type : 토큰의 타입을 지정
  • alg : 해싱 알고리즘 지정 , 토큰을 검증 할 때 사용되는 signature 부분에서 사용

Payload : 서버와 클라이언트가 주고받는 , 시스템에서 실제로 사용될 정보에 대한 내용

  • 토큰에 담을 정보
  • 여기에 담는 정보의 한 조각 을 클레임 (claim) 이라고 부르고 name / value 로 이루어져 있음
  • 토큰에는 여러 클레임을 담을 수 있다
클레임이란 ?

등록된 클레임

  • 서비스에서 필요한 정보들이 아닌, 토큰에 대한 정보들을 담기 위하여 이름이 이미 정해진 클레임
  • 사용은 모두 선택적
이름 설명
iss 토큰 발급자
sub 토큰 제목
aud 토큰 대상자
exp 토큰 만료 시간
nbf 토큰의 활성 날짜
iat 토큰이 발급된 시간
jti JWT 의 고유 식별자 , 중복 처리를 방지하기 위하여 사용

공개 클레임

  • 충돌이 방지된 이름을 가져야 함 , 충돌을 방지하기 위해서는 클레임 이름을 URI 형식으로 지음
    "https://soyeon.com/jwt_claims/is_admin": true
    

비공개 클레임

  • 양 측간에 (보통 클라이언트 ↔ 서버) 협의하에 사용되는 클레임 이름들
  • 공개 클레임과는 달리 이름이 중복되어 충돌이 될 수 있다
    username: "soyeon"
    

2개의 등록된 클레임 + 1개의 공개 클레임 + 2개의 비공개 클레임

{
	"iss": "naver.com",
	"exp": "1485270000000",
	"http://naver.com/jwt_claims/is_admin": true,
	"userId": "12",
	"username": "soyeon"
}

Signature : 토큰의 유효성 검증을 위한 문자열

  • 위 토큰이 유효한지 유효하지 않은지에 대한 정보를 가짐
  • 암호화에 사용되는 키 값은 서버에 저장해 놓음
  • 헤더의 인코딩 값과 정보의 인코딩값을 합친 후 주어진 비밀키로 해쉬를 하여 생성

사용방법

  • 생성된 토큰은 HTTP 통신 할 때 Authorization value 로 저장
    { 
     "Authorization": "Bearer {생성된 토큰 값}",
     }
    

장점 vs 단점

장점

  • 중앙의 인증서버, 데이터 스토어에 대한 의존성 없음 , 시스템 수평 확장 유리
  • Base64 URL Safe Encoding > URL, Cookie, Header 모두 사용 가능

단점

  • Payload 의 정보가 많아지면 네트워크 사용량 증가, 데이터 설계 고려 필요
  • 토큰이 클라이언트에 저장, 서버에서 클라이언트의 토큰을 조작할 수 없음

레퍼런스