쿠키 (Cookies)
서버에서 클라이언트에게 JWT 토큰을 쿠키에 저장하여 전송할 수 있다. 쿠키는 HTTP 요청 헤더에 자동으로 포함되므로, 클라이언트 및 서버 모두에서 쉽게 액세스할 수 있고 Secure 및 HttpOnly 플래그를 사용하여 보안을 강화할 수 있다. Secure 플래그는 HTTPS 연결을 통해만 쿠키가 전송되도록 보장하고, HttpOnly 플래그는 JavaScript에서 쿠키에 접근하는 것을 방지하여 XSS 공격을 예방한다.
// 회원 로그인 라우터
router.post('/login', async (req, res) => {
try {
// 이메일과 비밀번호를 이용하여 사용자를 인증하고 JWT 토큰 생성
const user = await User.findOne({ email: req.body.email });
if (!user || !await user.comparePassword(req.body.password)) {
return res.status(401).json({ message: '이메일 또는 비밀번호가 잘못되었습니다.' });
}
const token = jwt.sign({ userId: user._id }, secretKey, { expiresIn: '1h' });
// JWT 토큰을 쿠키에 저장
res.cookie('token', token, { httpOnly: true, secure: true, maxAge: 3600000 }); // 1시간 유효 기간
res.status(200).json({ success: true, message: '로그인 성공' });
} catch (err) {
console.error('로그인 오류:', err);
res.status(500).json({ message: '로그인 중 오류가 발생했습니다.' });
}
});
// 회원 로그아웃 라우터
router.post('/logout', async (req, res) => {
try {
// 쿠키에서 토큰 삭제
res.clearCookie('token');
res.status(200).json({ success: true, message: '로그아웃 되었습니다.' });
} catch (err) {
console.error('로그아웃 오류:', err);
res.status(500).json({ message: '로그아웃 중 오류가 발생했습니다.' });
}
});
쿠키 + HttpOnly
res.cookie('token', token, { httpOnly: true, secure: true, maxAge: 3600000 }); // 1시간 유효 기간
쿠키 + Secure
res.cookie('token', token, { secure: true, maxAge: 3600000 }); // 1시간 유효 기간
쿠키 + SameSite
res.cookie('token', token, { sameSite: 'strict', secure: true, maxAge: 3600000 }); // 1시간 유효 기간
HTTP 인증헤더
app.post('/login', (req, res) => {
// 사용자 인증 후 JWT 토큰 생성
const token = jwt.sign({ userId: user._id }, secretKey, { expiresIn: '1h' });
// HTTP 인증 헤더에 JWT 토큰 저장
res.setHeader('Authorization', `Bearer ${token}`);
res.send('로그인이 성공적으로 처리되었습니다.');
});
// 로그아웃 시 HTTP 인증 헤더에서 JWT 토큰 제거 (클라이언트는 헤더를 제거해야 함)
app.post('/logout', (req, res) => {
// 클라이언트가 HTTP 인증 헤더를 제거해야 함
res.send('로그아웃이 성공적으로 처리되었습니다.');
});
HTTP 인증 헤더는 토큰을 HTTP 요청 헤더에 직접 포함시켜 토큰이 쿠키 저장소에 노출되는 것을 방지한다.
또한 쿠키는 브라우저가 자동으로 모든 요청에 포함시키므로 CSRF 공격에 취약할 수 있는 반면 HTTP 인증헤더를 사용하면 CSRF(Cross-Site Request Forgery)를 방지 할 수 있다.
로컬 스토리지 (Local Storage)
클라이언트 측에서 JWT 토큰을 브라우저의 로컬 스토리지에 저장할 수 있다. 이 방법은 간단하고 사용하기 쉽지만, 보안상의 이유로 추천되지 않는다. 로컬 스토리지에 저장된 토큰은 JavaScript 코드에서 쉽게 액세스할 수 있으며, XSS(크로스 사이트 스크립팅) 공격에 취약할 수 있다.
// 로그인 후 로컬 스토리지에 토큰 저장
localStorage.setItem('token', token);
// 로그아웃 시 로컬 스토리지에서 토큰 제거
localStorage.removeItem('token');
세션 스토리지 (Session Storage)
로컬 스토리지와 유사하지만, 세션 스토리지에 저장된 데이터는 세션이 종료되면 제거된다. 세션 스토리지를 사용하면 토큰이 브라우저를 닫거나 탭을 닫을 때 자동으로 삭제된다. 그러나 여전히 XSS 공격에 취약할 수 있다.
// 로그인 후 세션 스토리지에 토큰 저장
sessionStorage.setItem('token', token);
// 로그아웃 시 세션 스토리지에서 토큰 제거
sessionStorage.removeItem('token');
웹 스토리지 API (Web Storage API)
웹 스토리지 API는 localStorage 및 sessionStorage를 포함하며, 이를 통해 클라이언트 측에서 데이터를 저장하고 검색할 수 있다. 보안 측면에서는 쿠키나 HTTP 인증 헤더를 사용하는 것이 더 안전하다.
'STUDY > NodeJS' 카테고리의 다른 글
Node.js와 JavaScript 구문의 차이점 (0) | 2024.04.04 |
---|---|
[1-1] dotenv로 환경변수 관리하기 (0) | 2024.03.29 |
[인증/권한] 클라이언트와 서버 간의 인증 JWT(JSON Web Token) (0) | 2024.03.28 |
비밀번호 해싱 처리를 위한 Mongoose 미들웨어 설정 (0) | 2024.03.27 |
npm install으로 패키지 설치시에 사용되는 옵션들 (0) | 2024.01.10 |