앞의 포스팅에서 JWT에 대한 기초적인 내용(https://velog.io/@jguuun/JWTBasic)을 올린 적 있는데, 최근에 Node.js로 JWT인증을 구현해보게 되었고 간략하게 코드를 통해 설명해보려 합니다!
npm init
npm i jsonwebtoken express
npm을 설정하고 jwt과 express를 설정합니다.
app.js
const express = require('express');
const jwt = require('jsonwebtoken');
const app = express();
const PORT = 3000;
const KEY = "test_key" // jwt만들 때 시크릿키로 사용
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html'); // 실습을 위한 인덱스 파일
});
/* 이후 코드가 들어갈 자리 */
app.listen(PORT, () => {
console.log(`Listening at http://localhost:${PORT}`);
});
index.html
<button onclick="create_token()">토큰 생성</button>
<button onclick="check_token()">토큰 확인</button>
<button onclick="remove_token()">토큰 삭제</button>
<script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
<body>
에 생성, 확인, 삭제를 하기 위해 버튼을 각각 생성합니다.app.js
app.get('/sign_token', (req, res) => {
let token = jwt.sign({ name: 'sancho', exp: parseInt(Date.now()/1000)+10 }, KEY); // 만료기간 10초
res.json({ token });
});
/sign_token
으로 GET
요청이 들어왔을 때 토큰을 생성하는 코드입니다.jwt.sign
이라는 함수로 name:'sancho'
라는 데이터와 만료기간을 10초로 설정하고 KEY
(시크릿키)로 암호화하여 토큰을 생성합니다.token
은 클라이언트로 반환합니다.index.html
function create_token() {
$.ajax({
type: 'GET',
url: `/sign_token`,
success: function (response) {
const token = response.token;
document.cookie = `token=${token};path=/`;
alert("생성 완료!")
},
error: function (xhr, textStatus, error) {}
});
}
/sign_token
의 주소로 GET
요청을 보냅니다.app.js
app.get('/check_token', (req, res) => {
let token = req.headers['token'];
try {
let payload = jwt.verify(token, KEY);
console.log('토큰 인증 성공', payload)
res.json({ msg: 'success' });
} catch (err) {
console.log("인증 에러");
res.status(405).json({ msg: 'error' });
next(err)
}
});
jwt.verify
함수로 시크릿키를 활용하여 복호화를 진행합니다.payload
에는 name:'sancho'
값이 담기게 됩니다.index.html
function getCookie(name) {
let matches = document.cookie.match(new RegExp('(?:^|; )' + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + '=([^;]*)'));
return matches ? decodeURIComponent(matches[1]) : undefined;
}
function check_token() {
let token = getCookie('token');
$.ajax({
type: 'GET',
url: `/check_token`,
headers: {"token":token},
success: function (response) {
alert("정상적인 토큰!");
},
error: function (xhr, textStatus, error) {
alert("만료된 토큰!");
}
});
}
getCookie(쿠키저장소 내 찾을 데이터)
함수를 만듭니다./check_token
으로 GET
요청합니다.index.html
function remove_token() {
document.cookie = `token=;max-age=-1;`;
alert("토큰 삭제 완료!");
window.location.reload();
}
token
을 지우기만 하면 됩니다.max-age
의 값을 음수로 하면 쿠키가 바로 지워집니다.위의 기능을 모두 구현한 모습입니다.
app.js
const express = require('express');
const jwt = require('jsonwebtoken');
const app = express();
const PORT = 3000;
const KEY = "test_key"
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html');
});
app.get('/sign_token', (req, res) => {
let token = jwt.sign({ name: 'sancho', exp: parseInt(Date.now()/1000)+10 }, KEY); // 만료기간 10초
res.json({ token });
});
app.get('/check_token', (req, res) => {
let token = req.headers['token'];
try {
let payload = jwt.verify(token, KEY);
console.log('토큰 인증 성공', payload)
res.json({ msg: 'success' });
} catch (err) {
console.log("인증 에러");
res.status(405).json({ msg: 'error' });
next(err)
}
});
function errorHandler(err, req, res, next) {
console.log("에러 처리 핸들러")
}
app.use(errorHandler);
app.listen(PORT, () => {
console.log(`Listening at http://localhost:/${PORT}`);
});
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>토큰 테스트</title>
<script>
function create_token() {
$.ajax({
type: 'GET',
url: `/sign_token`,
success: function (response) {
const token = response.token;
document.cookie = `token=${token};path=/`;
alert("생성 완료!")
},
error: function (xhr, textStatus, error) {}
});
}
function getCookie(name) {
let matches = document.cookie.match(new RegExp('(?:^|; )' + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + '=([^;]*)'));
return matches ? decodeURIComponent(matches[1]) : undefined;
}
function check_token() {
let token = getCookie('token');
$.ajax({
type: 'GET',
url: `/check_token`,
headers: {"token":token},
success: function (response) {
alert("정상적인 토큰!");
},
error: function (xhr, textStatus, error) {
alert("만료된 토큰!");
}
});
}
function remove_token() {
document.cookie = `token=;max-age=-1;`;
alert("토큰 삭제 완료!");
window.location.reload();
}
</script>
</head>
<body>
<button onclick="create_token()">토큰 생성</button>
<button onclick="check_token()">토큰 확인</button>
<button onclick="remove_token()">토큰 삭제</button>
</body>
<script
src="https://code.jquery.com/jquery-3.6.0.js"
integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk="
crossorigin="anonymous"
></script>
</html>