설치
$ yarn add jsonwebtoken dotenv
.env 파일
# jsonwebtoken
JWT_KEY = 12345678901234567890123456789012345678901234567890123
KEY 값은 다음 사이트를 참고해서 생성할 수 있다.
https://www.codegrepper.com/code-examples/javascript/random+jwt+secret+key+generator
users.js 파일
require('dotenv').config(); // .env variable
const jwt = require('jsonwebtoken');
const { auth } = require('../middleware/authMiddleware');
...
router.post('/login', (req, res, next) => {
const reqUsername = req.body.username;
const reqPassword = req.body.password;
if (!isAdmin(reqUsername)) {
return res.send(' <script> alert("admin의 로그인만 가능합니다."); location.href="/users/login"; </script> ');
}
const sql = 'SELECT * FROM users WHERE username = ? ';
const params = [ADMIN_ID];
db.query(sql, params, async (err, rows, fields) => {
if (err) return res.send(err);
const password = await makePasswordHashed(reqPassword, rows[0].salt);
if (rows[0].password === password) {
// JWT 생성
token = jwt.sign(
{
type: 'JWT',
id: 'admin',
},
JWT_KEY,
{
expiresIn: '60m',
}
);
res.cookie('user', token, {
httpOnly: true,
});
return res.send(' <script> alert("로그인 성공"); location.href="/"; </script> ');
} else return res.send(' <script> alert("비밀번호가 다릅니다."); location.href="/users/login"; </script> ');
});
});
...
JWT 생성 사용 방법은 payload, secretOrPrivateKey, [optinos, allback] 세 부분으로 나뉜다. payload는 실제 데이터를 싣는 공간이다. type에 JWT를 id에 admin 값을 싣었다. 보안키로 dotenv로 환경변수를 저장한 변수 JWT_KEY를 사용했다. 옵션으로 만료시간을 60분으로 설정했다.
jwt.sign(payload, secretOrPrivateKey, [options, callback])
만료 시간은 60, "2 days", "10h", "7d"의 형식으로 지정 가능하며 단위가 없으면 초 단위로 지정된다.
JWT 토큰은 선택에 의해 로컬 스토리지, 세션, 쿠키에 저장하는 방법을 선택한다. 장/단점이 서로 존재하므로 필요에 의한 방법을 선택하면 될 듯하다. res.cookie를 사용해 쿠키에 user 이름으로 token을 저장하는 과정에 옵션으로 httpOnly 설정을 추가했다. 이는 XSS 보안 취약점을 방지하기 위한 것이다.
middleware/authMiddleware.js 파일
require('dotenv').config();
const jwt = require('jsonwebtoken');
const JWT_KEY = process.env.JWT_KEY;
exports.auth = (req, res, next) => {
// 인증 완료
try {
// 요청 헤더에 저장된 토큰(req.headers.authorization)과 비밀키를 사용하여 토큰을 req.decoded에 반환
// req.decoded = jwt.verify(req.headers.authorization, JWT_KEY);
// 쿠키에 user 이름으로 JWT 저장
req.decoded = jwt.verify(req.cookies.user, JWT_KEY);
return next();
} catch (error) {
// 인증 실패
// 유효시간이 초과된 경우
if (error.name === 'TokenExpiredError') {
return res.status(419).json({
code: 419,
message: '토큰이 만료되었습니다.',
});
}
// 토큰의 비밀키가 일치하지 않는 경우
if (error.name === 'JsonWebTokenError') {
return res.status(401).json({
code: 401,
message: '유효하지 않은 토큰입니다.',
});
}
}
};
미들웨어 사용 방법
router.get('/token', auth, (req, res, next) => {
res.send(req.decoded);
});
/token 라우터에 auth 미들웨어를 사용해 디코더 된 값을 확인할 수 있다.
쿠키 삭제
router.get('/logout', (req, res, next) => {
res.clearCookie('user');
res.redirect('/');
});
쿠키 생성 및 삭제는 크롬 개발자 도구를 통해 확인 가능하다.
세부적인 내용은 jsonwebtoken npm 사이트에서 확인 가능하다.
https://www.npmjs.com/package/jsonwebtoken
'개발 > JS' 카테고리의 다른 글
논리 연산자(&&, ||), 삼항연산자를 사용한 단축 평가 (0) | 2022.01.11 |
---|---|
dotenv 환경변수 관리 (0) | 2021.12.30 |
[JS] 무작위로 배열 속 내용 추출하기 (0) | 2021.05.21 |
nodejs 재시작 없이 변경 내용 적용하기, supervisor 패키지 (0) | 2021.04.12 |
리액트 앱 만들어주는 앱 (0) | 2020.10.15 |
위치 정보 받아 날씨 제공 (0) | 2020.04.01 |