express-session 모듈에 대해 알아보자.
세션 (Session)
이전 포스팅에서 살펴본 쿠키(Cookie)는 클라이언트 측에 저장되기 때문에 보안이 취약한 단점이 있습니다.
세션은 저장하는 주체를 클라이언트가 아닌 서버로 옮겨 보안이 취약한 단점을 보안해줍니다.
쿠키로 실제 데이터가 아닌 식별값을 주고 서버에서는 쿠키 값을 통해 실제 데이터를 식별하고 조회해서 사용하도록 합니다.
서버에서 처리하는 만큼 서버의 부하가 커지지만 높은 보안성을 갖기 때문에 세션 방식이 더 많이 사용됩니다.
express-session 모듈
express-session 모듈은 세션 기능들을 모듈화한 것으로 따로 설치하고 설정해주어야합니다.
특정 사용자를 위한 데이터를 임시적으로 저장하며 세션은 사용자별로 req.session 객체
안에 유지됩니다.
설치
1
npm i express-session
express-session 설정
모듈을 import하고 session(Options)
형태로 미들웨어로 등록합니다.
Options
resave
- 요청이 왔을 때 세션에 수정사항이 없어도 저장할지 여부
saveUninitialized
- 세션에 저장할 내역이 없어도 처음부터 세션을 생성할 지
secret
- 암호화할 때 사용할 키
store
- 세션 저장 장소, 기본값은 메모리
cookie
- 세션 관리 시 클라이언트에 보내는 쿠키, 쿠키 설정과 동일
name
- 세션 쿠키명, 기본값은 ‘sid’
예시
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
import express from "express"; import session from "express-session"; import cookieParser from "cookie-parser"; const app = express(); app.use(cookieParser(process.env.COOKIE_SECRET)); app.use( session({ secure: true, secret: process.env.COOKIE_SECRET, resave: false, saveUninitialized: false, name: "sessionId", }) ); // 세션 미들웨어 등록 app.listen(3000, () => { console.log("express server on port 3000"); });
세션 접근
세션 객체에 req.session
으로 접근이 가능하다.
예시
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
import express from "express"; import session from "express-session"; import cookieParser from "cookie-parser"; const app = express(); app.use(cookieParser(process.env.COOKIE_SECRET)); app.use( session({ secure: true, secret: process.env.COOKIE_SECRET, resave: false, saveUninitialized: false, name: "sessionId", }) ); // 세션 미들웨어 등록 app.get("/session", (req, res) => { console.log(req.session); if (req.session.num === undefined) // 세션이 없다면 req.session.num = 1; // 세션 등록 else req.session.num += 1; res.send(`${req.session.num}번 접속`); }); app.listen(3000, () => { console.log("express server on port 3000"); });
http://localhost:3000/session 로 접속하면 num가 접속 할 때마다 1씩 올라가는 것을 확인할 수 있습니다.
console.log(req.session) 을 해보면 설정한 cookie와 등록한 num가 출력되는 것을 확인할 수 있습니다.
세션 삭제
req.session.(key)
형태로 세션에 접근했다면 세션을 제거할 때는 req.session.destroy
메서드를 사용합니다.
예시
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
import express from "express"; import session from "express-session"; import cookieParser from "cookie-parser"; const app = express(); app.use(cookieParser(process.env.COOKIE_SECRET)); app.use( session({ secure: true, secret: process.env.COOKIE_SECRET, resave: false, saveUninitialized: false, name: "sessionId", }) ); // 세션 미들웨어 등록 app.get("/session", (req, res) => { console.log(req.session); if (req.session.num === undefined) // 세션이 없다면 req.session.num = 1; // 세션 등록 else req.session.num += 1; res.send(`${req.session.num}번 접속`); }); app.get("/session/delete", (req, res) => { // 세션 삭제 req.session.destroy((err) => { if (err) throw err; res.redirect(302, "/session"); // 웹페이지 강제 이동 }); }); app.listen(3000, () => { console.log("express server on port 3000"); });
http://localhost:3000/session/delete 로 접속해 세션이 삭제되어
console.log(req.session)
출력 결과 num 삭제된 것을 확인할 수 있습니다.
Session Store
Session Store는 세션이 데이터를 저장하는 장소로 기본값은 Memory Store입니다.
Memory Store는 서버나 클라이언트가 꺼지면 사라지는 휘발성 데이터입니다.
따라서, 저희는 express-mysql-session 모듈
을 이용해 mysql
에 세션을 유지해보겠습니다.
express-mysql-session 모듈
express-mysql-session은 세션 데이터를 Mysql 서버에 저장하기 위한 express-session에 의존하는 모듈입니다.
npm 페이지를 참고해서 작성해보겠습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import express from "express";
import cookieParser from "cookie-parser";
import session from "express-session";
import mysqlStore from "express-mysql-session"; // express-mysql-session 모듈 import
const mysqlStoreSession = mysqlStore(session); // DB 연동 메서드
const options = {
host: process.env.DB_HOST, //실제로 연결할 데이터베이스의 위치
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
port: process.env.DB_PORT,
database: process.env.DB_DATABASE,
clearExpired: true, // 만료된 세션 자동 삭제 기능
checkExpirationInterval: 30 * 60 * 1000, // 30분 ,만료된 세션이 지워지는 빈도 (밀리초)
createDatabaseTable: true, // DB에 테이블이 없으면 생성할 지
expiration: 1 * 60 * 60 * 1000, // 1시간, 유효한 세션의 최대 시간 (밀리초)
schema: { // 생성 스키마
tableName: "sessions",
columnNames: {
session_id: "session_id",
expires: "expires",
data: "data",
},
},
};
const sessionStore = new mysqlStoreSession(options); // DB 정보 객체를 인자로 DB 연동
const app = express();
app.use(cookieParser(process.env.COOKIE_SECRET));
app.use(
session({
secure: true, // https 환경에서만 session 정보 처리
secret: process.env.COOKIE_SECRET, // 암호화하는 데 쓰일 키
resave: false, // 세션을 언제나 저장할지
saveUninitialized: false,
name: "sessionId",
store: sessionStore, // 세션 스토어 등록
cookie: {
maxAge: 24 * 60 * 60 * 1000, // 쿠키 유효기간 24시간
},
})
); // 세션 미들웨어 등록
... // 라우터
app.listen(3000, () => {
console.log("express server on port 3000");
});