본문 바로가기
개발정리 (nodeJS)

[nodeJS] Node.js에서 세션 관리 구현하기

by 할리갈리0 2024. 5. 29.

웹 애플리케이션에서 세션 관리는 사용자 인증과 상태 유지를 위해 매우 중요합니다.

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 애플리케이션을 개발할 수 있습니다.

반응형