✅ 토큰 기반 인증 시스템
🔸 개요
- 토큰은 로그인 이후 서버가 만들어 주는 문자열
- 해당 문자열 안에는 사용자의 로그인 정보와 해당 정보가 서버에서 발급되었음을 증명하는 서명이 들어있음
- 서명 데이터는 해싱 알고리즘을 통해 만들어지는데,
- 주로 HMAC SHA256, RSA SHA256 알고리즘 사용
- 토큰은 서명이 있기 때문에 무결성이 보장됨
🔸 시스템 흐름
- 사용자가 로그인 시 서버에게 토큰을 발급받고,
- 사용자는 추후 다른 API 요청시 토큰과 함께 요청하게 됨
- 서버는 토큰 유효성 검사를 하고, 결과에 따라 작업을 처리하고 응답
🔸 Stateless 서버
- 먼저, Stateful 서버는 클라이언트에게서 요청을 받을 때 마다, 클라이언트의 상태를 계속해서 유지하고, 이 정보를 서비스 제공에 이용
- 예를들어 유저가 로그인을 하면, 세션에 로그인이 되었다고 저장을 해 두고, 서비스를 제공 할 때에 그 데이터를 사용
- Stateless 서버는 반대로, 상태를 유지 하지 않음
- 상태정보를 저장하지 않으면, 서버는 사용자 측에서 가지고 있는 토큰을 포함해 들어오는 요청만으로만 작업을 처리
=> 서버 인스턴스가 여러 개로 늘어나도 서버끼리 사용자의 로그인 상태를 공유하고 있을 필요가 없음!!
- 이렇게 상태가 없는 경우 클라이언트와 서버의 연결고리가 없기 때문에,
- 서버 인스턴스가 여러 개로 늘어나도 서버끼리 사용자의 로그인 상태를 공유하고 있을 필요가 없음!!
- 즉, 서버의 확장성 (Scalability) 이 높아짐
✅ JWT
- JWT는 JSON Web Token의 약자로,
- 데이터가 JSON으로 이루어져 있는 토큰 의미
- 두 개체가 서로 안전하게 정보를 주고받을 수 있도록 웹표준(RFC 7519)으로 정의된 기술
- 자가 수용적 (self-contained)
- JWT 는 필요한 모든 정보를 자체적으로 지니고 있음
- JWT 시스템에서 발급된 토큰은, 토큰에 대한 기본정보, 전달 할 정보, 토큰이 검증됐다는것을 증명해주는 signature 를 포함
- 이같은 특징 덕에, JWT는 두 개체 사이에서 손쉽게 전달 될 수 있음
- 웹서버의 경우 HTTP의 헤더에 넣어서 전달 할 수도 있고, URL 의 파라미터로 전달 할 수도 있음
🔸 JWT의 생김새
- typ: 토큰의 타입을 지정 - JWT
- alg: 해싱 알고리즘을 지정
=> 보통 HMAC SHA256 혹은 RSA 가 사용
=> 토큰을 검증 할 때 사용되는 signature 부분에서 사용
{
"typ": "JWT",
"alg": "HS256"
}
🔹 Payload
- 토큰에 담기는 정보의 한 부분을 나타내는 클레임(claim)들로 이루어짐
- 클레임은 이름과 값으로 이루어진 쌍(pair)으로 구성
- 토큰을 생성하고 해석할 때 사용되는 중요한 데이터를 포함
- 등록된(registered) 클레임: 토큰에 대한 정보들을 담기위하여 이름이 이미 정해진 클레임
- 공개(public) 클레임: 충돌이 방지된(collision-resistant) 이름을 가지고 있어야 함
=> URI 형식
- 비공개(private) 클레임: 등록된 클레임도아니고, 공개된 클레임들도 아님
=> 양 측간에 (보통 클라이언트 <->서버) 협의하에 사용되는 클레임 이름들
{
// registered
"iss": "velopert.com",
"exp": "1485270000000",
// public
"https://velopert.com/jwt_claims/is_admin": true,
// private
"userId": "11028373727102",
"username": "velopert"
}
🔹 signature
- 헤더의 인코딩값과, 정보의 인코딩값을 합친후 주어진 비밀키로 해쉬를 하여 생성한 서명
✅ HTTP 인증과 Bearer
- 보통 HTTP 통신에서 인증을 하는 대표적인 2가지 방식이 있는데,
🔸 Basic
- 가장 기본적인 인증 방식
- 인증 정보로 사용자 ID, 비밀번호를 사용
- base64로 인코딩한 “사용자ID:비밀번호” 문자열을 Basic과 함께 인증 헤더에 입력
- 단순하고 구축하기 쉽다는 장점
- 서버에 사용자 목록을 저장해 서버 부담이 크고, 정교한 제어가 어렵다는 단점
🔸 Bearer
- “Bearer”은 소유자라는 뜻인데, “이 토큰의 소유자에게 권한을 부여해줘”(or “give access to the bearer of this token.”)라는 의미로 이름을 붙였다고 함
- Bearer 토큰은 원래 OAuth 2.0의 일부로 만들어졌지만, 따로 그 자체로도 많이 사용됨
- 사용할 때에는 Bearer와 토큰을 인증 헤더에 입력
- 토큰의 형태는 16진수의 문자열을 사용하기도 하고 JSON Web Token(JWT)을 사용하기도 함
- 중요한건 Bearer 토큰은 클라이언트가 해석할 수 없는 형태여야 하고, 사용자의 정보를 전달하면 안 됨
- 대신 서버에서 클라이언트의 권한을 확인할 수 있는 메타데이터가 토큰에 인코딩되어 있어야 하고,
- 충분히 복잡한 알고리즘을 사용해서 발급해야함
- 안전하고 확장이 쉽다는 장점
참고자료