JWT(JSON WEB TOKEN)는 사용자를 인증하고 식별하기 위한 일종의 인증 토큰이다.
기존에는 세션 등의 방법으로 사용자의 인증을 관리했지만 세션의 방식의 단점은 커넥트가 유지되어야 한다.
사용자가 적은 서비스라면 크게 상관없겠지만 사용자가 많아지면 서버의 비용 증가와 부하로 이어진다.
JWT의 핵심은 토큰 자체에 사용자의 권한이나 다양한 정보가 들어있고 무상태(Stateless) 환경에서도 데이터를 주고받을 수 있게 된다.
세션처럼 쿠키에 넣어서 서버 세션에 저장하는 게 아닌 사용자의 환경(저장소)에 보관할 수 있다.
요청을 보낼 때만 헤더나 바디에 실어 보내면 서버는 그때만 검증하면 되기에 효과적이다.
대략적인 방식은 아래와 같다.
물론 클라이언트에 있는 정보는 무엇이든 결코 안전하지 않다.
변조되거나 가로채 지기 쉽기 때문이다.
JWT는 이를 보완하기 위해 개인키를 통한 전자서명도 실시한다.
간단하게 설명하자면 서버에서 비밀키를 하나 가지고 있다. 이 키를 조합해서 암호화한 뒤 토큰을 만든다.
따라서 사용자가 받은 토큰은 사용자는 어떤 정보인지 알 수 없다.
단순히 들고 있다가 전달만 할 뿐 무언가 할 순 없다.
서버는 사용자로부터 토큰을 전달받으면 서버만 알고 있는 비밀키를 통해 복호화한다.
구조를 보면 크게 3가지 정보를 .으로 구분해서 합친 문자열이다.
우선 헤더에는 만들어진 토큰에서 사용할 알고리즘 종류 등이 담기고 Payload부분에 서버에서 사용자에 관련된
정보 등이 담겨있다. 마지막으로 Signature에는 헤더와 페이로드를 BASE64 방식으로 인코딩한 후 헤더에 명시된 암호화를 적용 후에 아까 서버만 들고 있다던 비밀키를 적용해서 전자서명을 한다. 방식은 다양하다.
복잡한 설명은 넘어가고 간략하게 알아봤으니 이제 간단하게 구현해보자.
직접 구현하는 건 필요성을 잘 몰라서 똑똑하신 분이 만들어둔 라이브러리를 활용하자.
내가 만들면 오히려 퍼포먼스가 더 낮을 거다.
npm을 통해 아래 라이브러리를 다운로드하자.
npm i jsonwebtoken
const secretKy = "TESTSECRETKEY"; // 이게 비밀키
const alg = "HS256"; //이런 해시 256알고리즘으로 암호화를 할거다.
const option = {expiresIn: "7d", issuer: "console2629", subject: "app"}
// expiresIn: 토큰의 유효기간이다. 7d는 발행일로부터 7일이다.
// issuer: 토큰을 발행한사람 명시
// subject: 사용될곳에 대한 설명
// 물론 옵션은 옵션일뿐 필수값은 아니다.
export const makeToken = (payload: any) => {
return jwt.sign({name: "가나다라", id: "test"}, secretKy, option);
}
export const decodeToken = (token: string) => {
return jwt.verify(token, secretKy);
}
위처럼 만들어두고 import 해서 아래처럼 사용하면 된다.
const c = {
name: "가나다라",
id: "test"
}
const token = makeToken(c)
console.log(token)
console.log(decodeToken(token))
이렇게 토큰을 생성과 분해 두 가지를 해보았다.
최근댓글