전자 서명된 URL-safe의 JSON
서버와 클라이언트 간 정보를 주고 받을 때 헤더에 포함된 JWT 정보를 통해 인증
서버 인증 방식(Cookie, Session): 기존 인증 시스템은 서버 기반 인증 방식으로 서버 측에서 사용자들의 정보를 기억하고 있어야 했다. 이를 위해 세션을 유지해야 하는데, 메모리, 디스크, DB 등을 통해 관리했었다.(stateful)
토큰 인증 방식: 인증받은 사용자들에게 토큰을 발급하고 서버에 요청했을 때, 헤더에 토큰을 보내 유효성 검사를 한다. 더이상 사용자의 인증 정보를 서버나 세션에 유지하지 않고 클라이언트에서 들어오는 요청만으로 작업을 처리한다.(stateless)
장점
단점
JWT는 헤더, 페이로드, 서명으로 구성되며, 각각은 점으로 구분한다.
header: 토큰 타입(토큰의 유형 JWT)과 해시 암호화 알고리즘(HMAC, SHA256, RSA 등) 정보. 헤더 파트가 base64로 인코딩 되어 첫 번째 파트에 들어가게 됨
{
"typ":"JWT",
"alg":"HS256"
}
payload: 토큰에 담을 클레임(정보의 한 조각) 정보 포함. 클레임은 name/value의 한 쌍으로 이루어져 있음
등록된 클레임(Register Claim): 서비스에서 필요한 정보들이 아닌, 토큰에 대한 정보들이 담겨져 있음
공개 클레임(Public Claim): 공개 클레임들은 충돌 방지된 이름을 가지고 있어야 함. 이를 위해 클레임 이름을 URI 형식으로 지음
{
"http://alwaysLee.com/jwt_claims/is_auth": true
}
비공개 클레임(Private Claim): 등록된 클레임도 아니고 공개된 클레임도 아닌 것. 클라이언트와 서버 간 협의하에 사용되는 클레임 이름들. 중복 사용 가능하는 유의할 것
{
"userName":"alwaysLee"
}
signature: secret key를 포함해 암호화 되어있음(헤더의 인코딩 값과 정보의 인코딩 값을 합친 후 주어진 비밀키로 해싱하여 생성).
//HMAC SHA256 알고리즘을 사용한다 가정
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
이를 통해, 메시지가 중간에 변경되지 않았음을 검증하며, JWT를 보낸 사람이 신뢰할 수 있는 대상인 것도 알 수 있음
최종적으로, 아래와 같은 Base64로 인코딩 된 문자열이 3개가 나옴
발급
const jwt = require('jsonwebtoken');
const token = jwt.sign({ foo: 'bar' }, 'secret-key', { expiresIn: '7d' }, (err, token) => {
if(err) {
console.log(err);
return;
}
console.log(token);
});
검증
const jwt = require('jsonwebtoken');
module.exports.check= (token)=>{
let check
try{
check= jwt.verify(token,'secret-key')
}catch(err){
console.log(err)
}
return check
}
https://www.freecodecamp.org/news/securing-node-js-restful-apis-with-json-web-tokens-9f811a92bb52/