2018년 4월 11일 수요일

Node.js - 스터디 3주차 - Session

https://opentutorials.org/course/2136/
생활코딩 강의를 이용해 진행하는 스터디 3주차.

4/12(목) :: 27강 'Session 1' 부터 29강 'Session 3' 까지.



Session 1


기본적인 상태유지 기능을 갖고 있지 않은 HTTP 프로토콜을 보완하기 위한 장치로 cookie와 session이 존재한다. 우선 기본은 cookie고, session는 cookie 기술을 바탕으로 동작하는 확장 기능 쯤으로 이해해보자.


session은 cookie와 다르게 정보를 사용자 컴퓨터에 저장하지 않고 서버에 저장한다. 특정 클라이언트에 대한 session 정보는 서버가 할당하는 session id를 통해 식별된다. (클라이언트(브라우저)는 서버로부터 session id를 전달받은 후 매 요청마다 session id를 헤더에 포함시키게 된다.) 결과적으로 클라이언트와 서버 간에는 session id만을 가지고 통신하기 때문에 session에 기록된 정보는 request, response 헤더에 드러나지 않는다. 따라서 request, response 헤더에 정보를 노출하는 cookie 방식에 비해 session이 보안상 안전하다고 말할 수 있다. 용량 제약이 큰 cookie에 비해 많은 양의 데이터를 session에 기록할 수 있다는 부분도 session이 가지는 장점이다.


하지만 session이 보안상, 공간상 장점이 있다고 해서 상태유지에 필요한 모든 사용자 데이터를 session에 저장하는 것은 옳지 않다. 서버의 성능에 무리를 줄 수 있기 때문이다. 따라서 보안에 신경쓰지 않아도 되는 가벼운 정보는 cookie로, 보안에 신경써주어야 하는 정보는 session으로 분리해서 관리하는 것이 옳다. 추가로 다른 프로그램과의 연동이 필요한 경우에 선택적으로 cookie를 활용할 수 있다.

cookie - 보안에 신경쓰지 않아도 되는 정보. (예 : '오늘 다시 알리지 않음'과 같은 팝업, 장바구니 목록 등.)

session - 보안에 신경써주어야 하는 정보. (예 : 사용자의 신원 데이터, 사용자의 로그인(접속) 정보 등.)

session 모듈을 설치하자.
npm install express-session --save

express-session 모듈의 경우 기본적으로 세션 정보를 메모리에 저장하므로 애플리케이션이 종료되면 모든 정보가 날아간다. 물론 데이터베이스를 이용해 세션 정보를 관리할 수도 있다.


다음은 간단한 테스트 앱이다. 일반 모드의 크롬 브라우저와 시크릿 모드의 크롬 부라우저를 띄운 뒤 session에 기록한 count 값이 어떻게 출력되는지 확인해보자.


var express = require('express');

var session = require('express-session');
var app = express();

app.use(session({

  secret: 'my-secret-key', // 이 키를 이용해 session id를 암호화 한다.
  resave: false, // 요청 중 session이 수정되지 않은 경우에도 session이 저장소에 다시 저장되도록 하는 옵션.
  saveUninitialized: true // 초기화되지 않은 session을 저장소에 저장하는 옵션. 잘 모르겠다.
}));

app.get('/', function(req, res) {

  if (req.session.count) {
    req.session.count++;
  } else {
    req.session.count = 1;
  }
  res.send('hi session: ' + req.session.count);
});

* 위 예제에서 보듯 req.session 객체에 원하는 값을 기록할 수 있다.

req.session.count = 1;

정보의 삭제는 'delete' 키워드를 이용해 프로퍼티 자체를 지우면 된다. 

delete req.session.count;


Session 2


session을 이용한 Login 앱 만들기. session을 이용하면 특정 사용자가 로그인 했을 때 로그인 정보를 애플리케이션 내에서 접근/관리할 수 있다. 단순하게 생각하는 편이 나은데 그냥 서버의 메모리에 기억하고 싶은 값을 기록하는 것 뿐이다. 이 값은 클라이언트에게 할당한 session id로 식별되고 변수 이름으로 참조된다.


1) 로그인 폼을 만들어 화면에 표시한다.


2) 로그인 요청에 대한 처리 기능을 만든다. 유효한 로그인이면 필요한 정보를 session에 기록하고 welcome 페이지로 전환한다.


3) welcome 페이지는 session 정보를 참조해서 화면을 표시한다.


4) 로그아웃을 요청하면 session 정보를 삭제한다.



Session 3


session 데이터를 메모리에 보관하는 방법은 실제 서비스에선 잘 사용하지 않는 방법이다. npm 모듈 페이지에서도 아래와 같이 안내되고 있다.

Warning: The default server-side session storage, MemoryStore, is purposely not designed for a production environment. It will leak memory under most conditions, does not scale past a single process, and is meant for debugging and developing.

강의에선 파일, MySQL, OrientDB 각각의 저장소를 이용해 session 데이터를 관리하는 방법을 알려주고 있다.


1) 파일

npm install session-file-store --save

var session = require('express-session');
var FileStore = require('session-file-store')(session);

app.use(session({
  ...
  store: new FileStore({ path: './sessions/' })
  ...
}));


2) MySQL

npm install express-mysql-session --save

var session = require('express-session');
var MySQLStore = require('express-mysql-session')(session);

app.use(session({
  ...
  store: new MySQLStore({
    host: 'localhost',
    port: 3306,
    user: 'root',
    password: '111111',
    database: 'o2'
  })
}));
→ MySQL 접속 정보를 같이 지정해준다. express-mysq-session 모듈은 전달받은 DB 접속 경로에 sessions라는 테이블을 생성하고, session 데이터에 대한 CRUD를 대신 수행해준다.




! 한가지 주의할 점이 있다. session 정보를 변경한 후 redirect를 호출하면 redirect된 화면에서 최신 session 정보를 읽어오지 못할 때가 있다. session 데이터 수정 후에 redirect가 필요하면 우선 save를 호출한 후 callback에서 redirect를 요청하도록 해주자.

req.session.save(function() {
  res.redirect('/welcome');
});


3) OrientDB

OrientDB를 session 저장소로 사용하는 방법은 MySQL 버전과 매우 유사하다.
npm install connect-oriento --save

사용법: https://www.npmjs.com/package/connect-oriento

댓글 없음:

댓글 쓰기