[Node.js] Session

유동균·2023년 2월 5일
0

Node.js

목록 보기
6/11
post-thumbnail

1. Session이란?

  • 세션은 특정 사용자로부터 들어오는 일련의 요청을 하나의 상태로 보고 그 상태를 일정하게 유지시키는 기술로 쿠키와 상당히 유사하지만,

  • 쿠키는 사용자 정보 파일을 사용자 컴퓨터 메모리에 저장하는 것이고 세션은 사용자 정보 파일을 서버 측에서 관리한다는 차이점이 있다.

  • Session은 웹 어플리케이션의 사용자가 접속하는 동안 매 요청마다 유지되는 데이터의 집합을 말한다. 세션은 웹 서버에 저장되어지며, 클라이언트에서 사용자를 식별하기 위해 쿠키 또는 기타 방식을 사용할 수 있다.

  • Express에서는 Session 기능을 위해 미들웨어인 express-session을 사용할 수 있다. express-session 미들웨어를 사용하면 세션 데이터를 쉽게 관리할 수 있는데,

  • 예를 들어, 사용자의 로그인 정보를 저장하거나 사용자의 기본 정보를 유지할 수 있습니다.

2. 세션의 동작 순서

  • Express를 사용한 웹 애플리케이션에서, 세션은 사용자의 데이터를 여러 요청에 걸쳐 유지하는 방법이다.
  1. 클라이언트 요청 (사용자가 웹사이트 접근)
  2. 서버는 접근클라이언트의 Request-Header필드인 cookie를 확인하여, 클라이언트가 해당 세션ID를 보냈는지 확인
  3. 세션ID가 존재하지 않는다면, 서버는 세션ID를 생성해 클라이언트에게 전송.
  4. 서버에서 클라이언트로 준 세션ID를 쿠키를 사용해 서버에 저장한다.
  5. 클라이언트는 재접속시, 이 쿠키를 이용하여 세션ID값을 서버에 전달한다.

3. express-session

  • express-session은 Express.js 프레임워크에서 사용자 세션 데이터를 관리하고 유지할 수 있는 방법을 제공하는 미들웨어다.
  • 이 미들웨어를 사용하면 메모리나 데이터베이스에 세션 데이터를 저장하고, 사용자의 각 추가 요청에 대해 서버 측에서 접근할 수 있다.
  • 세션 데이터는 사용자 환경 설정, 쇼핑 카트 내용, 인증 상태 등의 정보를 저장하는데 사용할 수 있으며, 여러 요청 사이에 유지된다.
  • express-session을 사용하려면 Express.js 응용 프로그램에서 종속성으로 설치한 다음, 저장 매커니즘과 세션 옵션 (예를 들어 세션의 최대 나이) 등을 구성하면 된다.

3.1 Install

> npm install express-session

3.2 Usage

  1. 애플리케이션을 생성하고, express-session 모듈을 추가
const express = require('express');
const session = require('express-session');
const app = express();
  1. express-session 미들웨어를 애플리케이션에 추가합니다.
app.use(session({
  secret: 'secret-key',  
  resave: false,   
  saveUninitialized: false,
  cookie: {
    maxAge: 60 * 60 * 1000
  }
}));

req.session 프로퍼티의 의미

  • secret: 세션 ID 쿠키를 서명하는 데 사용할 문자열. 보안 목적으로 필수적.
  • resave: 수정되지 않은 세션일지라도 다시 저장할지(세션을 언제나 저장할지) 나타내는 부울 값. 기본값은 false.
  • saveUninitialized: 초기화되지 않은 세션을 저장할지(세션에 저장할 내역이 없더라도 처음부터 세션을 생성할지) 나타내는 부울 값. 기본값은 true.
  • cookie: 세션 ID 쿠키의 옵션을 지정하는 객체,
    • maxAge (쿠키의 유효 기간, 밀리초 단위),
    • secure (쿠키가 보안 연결에서만 전송되어야함을 나타내는 것),
    • httpOnly (쿠키가 HTTP 프로토콜을 통해서만 접근 가능해야함을 나타내는 것).
  • store: 세션 데이터의 저장 메커니즘, 예를 들어 메모리 (인 메모리 저장소) 또는 connect-mongo처럼 MongoDB 데이터베이스에 세션 데이터를 저장하는 세션 저장소.
const session = require('express-session');

app.use(session({
 secure: true,  // https 환경에서만 session 정보를 주고받도록처리
 secret: 'secret-key',
 resave: false,
 saveUninitialized: true,
 cookie: {
   maxAge: 1000 * 60 * 60 * 24, // 24 hours
   secure: true,
   httpOnly: true
 },
 store: new MongoStore({
   url: 'mongodb://localhost/sessions'
 })
}));
app.get('/', (req, res, next) => {
// 세션에 데이터를 설정하면, 모든 세션이 설정되는게아니라, 요청 받은 고유의 세션 사용자의 값만 설정.
// 즉, 개인의 저장 공간이 생긴 것과 같다.
req.session.id = "hello"; 
}
  1. 원하는 라우트에서 세션 데이터를 저장하고 가져온다.
app.get('/', (req, res) => {
  if (req.session.views) {
    req.session.views++;
  } else {
    req.session.views = 1;
  }
  res.send(`You visited this page ${req.session.views} times.`);
});
  1. 애플리케이션을 실행
app.listen(3000, () => {
  console.log('Listening on http://localhost:3000');
});
예제
// express 모듈을 가져옵니다.
const express = require('express');
// express-session 모듈을 가져옵니다.
const session = require('express-session');
// express 애플리케이션을 생성합니다.
const app = express();

// session 미들웨어를 사용합니다.
app.use(session({
  // secret 키는 세션의 암호화에 사용됩니다.
  secret: 'keyboard cat',
  // resave 옵션은 세션이 변경되지 않아도 저장할지 여부를 나타냅니다. false로 설정되어 있으면 변경되지 않았다면 저장하지 않습니다.
  resave: false,
  // saveUninitialized 옵션은 초기화되지 않은 세션을 저장할지 여부를 나타냅니다. true로 설정되어 있으면 초기화되지 않은 세션도 저장합니다.
  saveUninitialized: true,
  // cookie 옵션은 세션 ID 쿠키에 대한 옵션입니다.
  cookie: { 
    // secure 옵션은 쿠키를 암호화된 HTTPS 연결으로만 전송할지 여부를 나타냅니다. false로 설정되어 있으면 HTTP와 HTTPS 모두에서 전송됩니다.
    secure: false 
  }
}));

app.get('/', function(req, res) {
  // 세션에 "views"라는 속성이 있는지 확인합니다. 없으면 0으로 설정합니다.
  req.session.views = (req.session.views || 0) + 1;
  // 클라이언트에 "Views: {뷰의 수}"라는 응답을 보냅니다.
  res.send(`Views: ${req.session.views}`);
});

app.listen(3000, function() {
  console.log('Example app listening on port 3000!');
});

3.3 session 접근하기

  • 세션 객체에 req.session으로 접근 가능
app.get('/', (req, res, next) => {
  if (req.session.num === undefined) // 세션이 없다면
    req.session.num = 1; // 세션 등록
  else
    req.session.num += 1;
    
  res.send(`${req.session.num}번 접속`);
});
  • 같은 세션을 유지하고 있는 한 루트 path로 접속을 할 때마다 req.session.num이 1씩 늘어나게 된다.
    이런 식으로 req.session.is_logined를 하면 로그인을 했는지 안 했는지 구현할 수도 있다.

  • 세션 객체를 없애고 싶다면(가령 로그아웃을 해서 세션을 유지할 필요가 없어진다면) req.session.destroy를 하면 된다.

req.session.destroy(err => {
  if (err) throw err;
  res.redirect(302, '/'); // 웹페이지 강제 이동 
});
  • 만약 세션 스토어가 바쁠 때 리다이렉션을 하면 바로 결과가 반영되지 않을 수도 있다.
    그럴 때는 req.session.save(err => {})를 하면 된다.
    req.session.save를 실행하면 즉시 session 데이터 저장을 하고, err를 매개변수로 갖는 콜백 함수는 save가 모두 끝나면 작업할 내용들을 담고 있다.
if (email === authData.email && pwd === authData.pwd) {
  req.session.is_logined = true;
  req.session.nickname = authData.nickname;
  req.session.save(err => {
    if (err) throw err;
    res.redirect(302, '/');
  });
} else {
  res.end("Who?");
}
  • 세션은 서버 메모리(MemoryStore)에 저장된다. 즉, 서버가 한 번 내려가면 모두 초기화돼서 없어진다는 뜻

0개의 댓글