[Node.js] 익스프레스 - 세션 처리하기 (로그인, 로그아웃 구현)

세션 처리하기

세션은 쿠키와 달리 서버 쪽에 상태 정보를 저장한다. 세션의 대표적인 예는 로그인 했을 때 저장되는 세션을 들 수 있다. 로그인하면 세션이 만들어지고 로그아웃하면 세션이 삭제되는 기능을 만들면 사용자가 로그인하기 전에는 접근 제한된 페이지를 보지 못하도록 설정할 수 있다.

상품 페이지 로그인, 로그아웃 구현하기

이전에 만든 로그인 페이지의 코드에 세션 처리를 추가해서 상품 페이지를 만들어보자. 로그인과 로그아웃을 세션으로 구현할 것이다.

우선 express-session 모듈을 cmd에서 npm i express-session --save로 설치한다. 세션을 사용할 때는 쿠키도 같이 사용하므로 cookie-parser 모듈도 함께 불러들여야 한다.

사용할 파일은 3개이다. 이전 로그인 페이지 구현하기 포스팅을 보면 이해가 쉽다.

[프로젝트폴더]/public/login.html
[프로젝트폴더]/public/product.html
[프로젝트폴더]/app.js

/public/login.html
<!DOCTYPE HTML>
<html>
<head>
    <meta charset="UTF-8">
    <title>로그인</title>
</head>
<body>
    <h1>로그인</h1>
    <br>
    <form method="post" action="/process/login">
        <table>
            <tr>
                <td><label>아이디</label></td>
                <td><input type="text" name="id"></td>
            </tr>
            <tr>
                <td><label>비밀번호</label></td>
                <td><input type="password" name="password"></td>
            </tr>
        </table>
        <input type="submit" value="전송" name="">
    </form>
</body>
</html>
cs

/public/product.html
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>상품 페이지</title>
</head>
<body>
    <h3>상품정보 페이지</h3>
    <hr />
    <p>로그인 후 볼 수 있는 상품정보 페이지입니다</p><br>
    <a href='/process/logout'>로그아웃</a>
</body>
</html>
cs

app.js
var express = require('express'),
    http = require('http'),
    path = require('path'),
    bodyParser = require('body-parser'),
    static = require('serve-static'),
    cookieParser = require('cookie-parser'),
    expressSession = require('express-session');
var app = express();
app.use(cookieParser());
app.use(expressSession({
    secret: 'my key',
    resave: true,
    saveUninitialized: true
}));
var router = express.Router();
app.use(bodyParser.urlencoded({
    extended: false
}));
app.use(bodyParser.json());
app.use('/public', static(path.join(__dirname, 'public')));
router.route('/process/product').get(function (req, res) {
    console.log('/process/product 호출됨');
    if (req.session.user) {
        res.redirect('/public/product.html');
    } else {
        res.redirect('/public/login.html');
    }
})
router.route('/process/login').post(function (req, res) {
    console.log('/process/login 호출됨');
    var paramId = req.body.id || req.query.id;
    var paramPw = req.body.password || req.query.password;
    if (req.session.user) {
        console.log('이미 로그인되어 상품페이지로 이동');
        res.redirect('/public/product.html');
    } else {
        req.session.user = {
            id: paramId,
            name'zini',
            authorized: true
        };
        res.writeHead('200', {
            'Content-Type''text/html;charset=utf8'
        });
        res.write('<h1>로그인 성공</h1>');
        res.write('<div><p>Param ID: ' + paramId + '</p></div>');
        res.write('<div><p>Param PW: ' + paramPw + '</p></div>');
        res.write("<br><a href='/process/product'>상품 페이지로 이동</a>");
        res.end();
    }
});
router.route('/process/logout').get(function(req, res){
    console.log('/process/logout 호출됨');
    
    if(req.session.user){
        console.log('로그아웃');
        
        req.session.destroy(function(err){
            if(err) throw err;
            console.log('세션 삭제하고 로그아웃됨');
            res.redirect('/public/login.html');
        });
    }
    else{
        console.log('로그인 상태 아님');
        res.redirect('/public/login.html');
    }
});
app.use('/', router);
http.createServer(app).listen(3000function () {
    console.log('Express 서버가 3000번 포트에서 시작');
})
cs

우선 세션이 있을 때(로그인 상태)와 없을 때 처리하는 방식이 달라지므로 전체 처리 과정이 약간 복잡하다.

먼저 사용자가 상품 정보를 웹 서버에 요청한다. (localhost:3000/process/product로 접근)

웹 서버에서는 /process/product 패스를 라우팅하여 처리하는데 그 안에서 user라는 이름의 세션이 있는지 확인한다. 만약 이미 저장된 user 세션이 있다면 (로그인 상태) 클라이언트에 /public/product.html 파일로 리다이렉트하고, 아니라면 로그인 페이지(/public/login.html)로 리다이렉트한다.

로그아웃 처리는 /process/logout 패스로 처리한다. session 객체에 정의된 destroy() 메소드를 호출하여 세션을 제거한다. 세션을 없앤 후 로그인 페이지로 리다이렉트한다.

서버를 실행한 후 localhost:3000/process/product로 접속하면 처음에는 user 세션 객체가 만들어져 있지 않으므로 로그인 페이지로 리다이렉트 될 것이다.

댓글 없음:

Powered by Blogger.