웹 애플리케이션에서 세션 관리는 사용자 인증과 상태 유지를 위해 매우 중요합니다.
Express-session을 사용해 Node.js 애플리케이션에서 사용자 세션을 관리하는 방법을 설명하겠습니다.
1. 세션(Session) 이해하기
세션은 서버 측에 사용자 정보를 저장하는 방식입니다.
사용자가 웹사이트를 방문할 때 서버는 고유한 세션 ID를 생성하고, 이를 클라이언트(브라우저)에 쿠키로 전달합니다.
클라이언트는 이 쿠키를 통해 서버와 통신하며, 서버는 세션 ID를 기반으로 사용자의 상태와 정보를 추적합니다.
[세션의 역할]
- 로그인 상태 유지: 사용자가 로그인한 후, 다른 페이지로 이동하더라도 로그인 상태 유지 가능
- 사용자 맞춤형 설정: 사용자별로 다른 설정이나 데이터 유지 가능
- 쇼핑 카트: 전자 상거래 사이트에서 장바구니에 담긴 상품 유지 가능
2. Express-session 모듈 소개 및 설치
express-session : Express 애플리케이션에서 세션 관리를 쉽게 구현할 수 있게 해주는 미들웨어
npm install express-session
3. 기본 세션 설정 및 사용하기
아래 코드를 실행한 후 브라우저에서 http://localhost:3000을 여러 번 새로고침하면 세션을 통해 방문 횟수를 추적하고 있기 때문에 "Views: " 숫자가 증가.
const express = require('express');
const session = require('express-session');
const app = express();
const port = 3000;
// express-session 미들웨어를 설정
app.use(session({
secret: 'your_secret_key',
resave: false,
saveUninitialized: true,
cookie: { secure: false } // HTTPS 사용 시 true로 설정
}));
app.get('/', (req, res) => {
if (!req.session.views) {
req.session.views = 1;
} else {
req.session.views++;
}
res.send(`Views: ${req.session.views}`);
});
app.listen(port, () => {
console.log(`Server running on port ${port}`);
});
[옵션 설명]
1. secret
- 세션을 암호화하기 위한 키
2. resave
- 세션이 수정되지 않더라도 세션을 다시 저장할지 여부를 결정 (기본값 true)
- true일 경우: 각 요청마다 세션이 다시 저장. 이는 모든 요청마다 세션이 업데이트되는 애플리케이션에 유용
- false일 경우: 세션이 변경되지 않는 한 저장되지 않아 대부분의 애플리케이션에서 권장
3. saveUninitialized
- 초기화되지 않은 세션을 저장할지 여부를 결정
- 초기화되지 않은 세션은 새로 만들어졌지만 변경되지 않은 세션 (기본값 true)
- true일 경우: 세션이 새로 생성되면 비어 있더라도 저장. 로그인 페이지와 같은 상황 사용
- false일 경우: 세션이 변경되지 않는 한 저장되지 않음. 저장 공간을 절약하고, 사용되지 않는 세션이 저장되는 것을 방지
4. 세션 저장소 설정 및 관리
기본적으로 Express-session은 메모리에 세션을 저장하지만 애플리케이션이 재시작될 때 세션이 사라지므로, Redis와 같은 외부 저장소를 사용하여 세션을 관리 가능
npm install redis connect-redis
세션 데이터는 Redis에 저장되며, 애플리케이션이 재시작되어도 세션 유지 가능
const RedisStore = require('connect-redis')(session);
const redis = require('redis');
const redisClient = redis.createClient();
// Redis 클라이언트와 Connect-Redis를 설정
app.use(session({
store: new RedisStore({ client: redisClient }),
secret: 'your_secret_key',
resave: false,
saveUninitialized: false,
cookie: { secure: false } // HTTPS 사용 시 true로 설정
}));
5. 프론트엔드와 백엔드 연동하기
[로그인 예제]
백엔드 (Node.js)
const express = require('express');
const session = require('express-session');
const bodyParser = require('body-parser');
const app = express();
const port = 3000;
// 세션 설정
app.use(bodyParser.urlencoded({ extended: false }));
app.use(session({
secret: 'your_secret_key',
resave: false,
saveUninitialized: true,
cookie: { secure: false }
}));
// 가상의 사용자 데이터베이스
const users = {
user1: { password: 'password1' },
user2: { password: 'password2' }
};
// 로그인 라우트
app.post('/login', (req, res) => {
const { username, password } = req.body;
if (users[username] && users[username].password === password) {
req.session.user = username;
res.send('로그인 성공');
} else {
res.send('로그인 실패');
}
});
// 로그인 상태 확인 라우트
app.get('/status', (req, res) => {
if (req.session.user) {
res.send(`로그인 상태: ${req.session.user}`);
} else {
res.send('로그인되지 않음');
}
});
// 로그아웃 라우트
app.get('/logout', (req, res) => {
req.session.destroy();
res.send('로그아웃 성공');
});
app.listen(port, () => {
console.log(`Server running on port ${port}`);
});
프론트엔드 (HTML + Fetch API)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>세션 예제</title>
</head>
<body>
<h1>세션 예제</h1>
<form id="loginForm">
<input type="text" id="username" placeholder="사용자명" required>
<input type="password" id="password" placeholder="비밀번호" required>
<button type="submit">로그인</button>
</form>
<button id="checkStatus">로그인 상태 확인</button>
<button id="logout">로그아웃</button>
<p id="message"></p>
<script>
document.getElementById('loginForm').addEventListener('submit', function(event) {
event.preventDefault();
const username = document.getElementById('username').value;
const password = document.getElementById('password').value;
// Fetch API로 로그인 요청
fetch('/login', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: `username=${username}&password=${password}`
})
.then(response => response.text())
.then(data => {
document.getElementById('message').innerText = data;
});
});
document.getElementById('checkStatus').addEventListener('click', function() {
fetch('/status')
.then(response => response.text())
.then(data => {
document.getElementById('message').innerText = data;
});
});
// 로그인 상태를 확인하여 로그아웃 요청 처리
document.getElementById('logout').addEventListener('click', function() {
fetch('/logout')
.then(response => response.text())
.then(data => {
document.getElementById('message').innerText = data;
});
});
</script>
</body>
</html>
세션은 사용자 인증, 상태 유지, 개인화된 경험 제공 등 다양한 용도로 활용될 수 있습니다.
세션을 통해 더 안전하고 효율적인 Node.js 애플리케이션을 개발할 수 있습니다.
'개발정리 (nodeJS)' 카테고리의 다른 글
[nodeJS] Node.js로 tRPC API 만들기 (0) | 2024.07.11 |
---|---|
[nodeJS] Node.js에서 대규모 파일 업로드 처리하기 (0) | 2024.06.28 |
[nodeJS] Node.js에서 스케줄링 작업 자동화하기 (0) | 2024.05.28 |
[nodeJS] Node.js로 페이징네이션 활용하기 (0) | 2024.05.23 |
[nodeJS] Node.js와 redis 연동하기 (0) | 2024.05.07 |