JWT 는 JSON Web Token의 약자로 전자 서명 된 URL-safe (URL로 이용할 수있는 문자 만 구성된)의 JSON입니다.
전자 서명은 JSON 의 변조를 체크 할 수 있게되어 있습니다.
JWT는 속성 정보 (Claim)를 JSON 데이터 구조로 표현한 토큰으로 RFC7519 표준 입니다.
JWT는 서버와 클라이언트 간 정보를 주고 받을 때 Http 리퀘스트 헤더에 JSON 토큰을 넣은 후 서버는 별도의 인증 과정없이 헤더에 포함되어 있는 JWT 정보를 통해 인증합니다.
이때 사용되는 JSON 데이터는 URL-Safe 하도록 URL에 포함할 수 있는 문자만으로 만듭니다.
JWT는 HMAC 알고리즘을 사용하여 비밀키 또는 RSA를 이용한 Public Key/ Private Key 쌍으로 서명할 수 있습니다.
그렇다고한다.
json 으로 표현되어 클라이언트-서버 통신간 인증시 사용한다.
를 들어가보면 토큰이 어떤 정보를 담고있는지 확인해 볼 수 있다.
위 사진이 프로세스를 이해하는데 큰 도움을 줄것이다.
토큰을 두가지로 나누어 보안성을 높일 수 있다.
Access Token은 리소스에 직접 접근할 수 있도록 해주는 정보를 가지고 있고, 짧은 수명을 가지며 세션에 담아서 관리한다.
Refresh Token은 새로운 Access Token을 발급받기 위한 정보를 가지며, 긴 수명을 가지고, 노출되면 안되므로 데이터베이스에 저장한다.
+) Access Token을 쿠키에 저장해서, HttpOnly 옵션을 주면 javasciprt로 접근이 불가능 하기 때문에 쿠키에 저장할 수 있다.
쿠키를 사용하는 것이 세션을 관리하는 것이아닌, 쿠키를 정보 전송 수단으로 사용하여 stateless 하다.
토큰을 발급하는 API와
미들웨어로 토큰을 체크하는 함수 두가지를 만들어보자
controller/user.ctrl.js
exports.get_token = async (req, res, next) => {
const userid = req.params.user_id;
try {
const token = jwt.sign({
id: userid,
}, (process.env.JWT_SECRET || 'JWT_SECRET'), {
expiresIn: '30m',
issuer: 'get_token_controller',
});
res.status(200).send(token);
} catch (e) {
console.error(e);
next(e);
}
};
middleware/token.js
const jwt = require('jsonwebtoken');
exports.verifyToken = (req, res, next) => {
try {
req.decoded = jwt.verify(req.headers.authorization, process.env.JWT_SECRET || 'JWT_SECRET');
return next();
} catch (error) {
if (error.name === 'TokenExpiredError') {
return res.status(419).json({
code: 419,
message: '토큰이 만료되었습니다',
});
}
return res.status(401).json({
code: 401,
message: '유효하지 않은 토큰입니다',
});
}
};
jwt.sign
jwt.verify
두가지 함수만 사용할 줄 알면된다.
payload (사용자정보) 와 secret key로 sign 하여 token을 발급하여 클라이언트에게 반환하고
authorization header에 담긴 token을 secret key로 verifiy한다
refresh token 까지 사용할 경우
토큰 발급 요청시 두가지 토큰을 동시에 반환하고, 사용자는 refresh token은 저장해놓고 access token 으로 req를 보낸다
서버는 access token을 검증 하다가, 만료된 토큰이 들어오면 만료된 토큰임을 고지하고,
클라이언트는 이때 저장된 refresh token을 함께 전송하여 새로운 access token을 다시 발급받아 이 토큰으로 새로운 요청을 진행한다.
=>
토큰을 두개로 나누지만, 어차피 refresh token 이 탈취당할 위험은 똑같이 존재...하는거같습니다
그래서 refresh token 도 만료기한이 필수인거같군요.