๋ฏธ๋ค์จ์ด
๋ฏธ๋ค์จ์ด๋ ์ต์คํ๋ ์ค์ ํต์ฌ์ด๋ค. ์์ฒญ๊ณผ ์๋ต์ ์ค๊ฐ(middle, ๋ฏธ๋ค)์ ์์นํ์ฌ ๋ฏธ๋ค์จ์ด๋ผ๊ณ ๋ถ๋ฅธ๋ค. ๋ฏธ๋ค์จ์ด๋ ์์ฒญ๊ณผ ์๋ต์ ์กฐ์ํ์ฌ ๊ธฐ๋ฅ์ ์ถ๊ฐํ๊ธฐ๋ ํ๊ณ , ๋์ ์์ฒญ์ ๊ฑธ๋ฌ๋ด๊ธฐ๋ ํ๋ค.
๋ฏธ๋ค์จ์ด๋ ์ฃผ๋ก app.use์ ํจ๊ป ์ฌ์ฉ๋๋ค.

app.use์ ์ธ์๋ก ๋ค์ด ์๋ ํจ์๊ฐ ๋ฏธ๋ค์จ์ด์ด๋ค. ๋ฏธ๋ค์จ์ด๋ use ๋ฉ์๋๋ก app์ ์ฅ์ฐฉํ๋ค. ์ ์ผ ์์ logger('dev')๋ถํฐ ์์ํ์ฌ ๋ฏธ๋ค์จ์ด๋ค์ ์์ฐจ์ ์ผ๋ก ๊ฑฐ์น ํ ๋ผ์ฐํฐ์์ ํด๋ผ์ด์ธํธ๋ก ์๋ต์ ๋ณด๋ธ๋ค.

1. ์ปค์คํ ๋ฏธ๋ค์จ์ด ๋ง๋ค๊ธฐ
์์ฒญ์ด ๋ค์ด์ฌ ๋ ์ฝ์์ ๋ฉ์์ง๋ฅผ ์ฐ๋ ๋จ์ํ ๋ฏธ๋ค์จ์ด๋ฅผ ๋ง๋ค์ด๋ณด์. app.js์์ logger๋ณด๋ค ์์ ๋ค์ ์ฝ๋๋ฅผ ์ ์ด์ค๋ค.

app.js ํ์ผ์ ์ ์ฅํ๊ณ ์๋ฒ๋ฅผ ์คํํ๋ค.



์์ฒญ ๋ ๊ฐ, ์ฆ GET /์ GET /stylesheet.style.css๊ฐ ์๋ฒ๋ก ์ ๋ฌ๋์๋ค. ๊ฐ๊ฐ์ ์์ฒญ์ด ๋ชจ๋ ๋ฐฉ๊ธ ๋ง๋ ์ปค์คํ ๋ฏธ๋ค์จ์ด๋ฅผ ์๋์์ผฐ๋ค. ์ด๋ ๊ฒ ์๋ฒ๊ฐ ๋ฐ์ ์์ฒญ์ ๋ฏธ๋ค์จ์ด๋ฅผ ํ๊ณ ๋ผ์ฐํฐ๊น์ง ์ ๋ฌ๋๋ค.
์ฃผ์ํด์ผํ ์ ์ด ์๋ค. ๋ฐ๋์ ๋ฏธ๋ค์จ์ด ์์์ next()๋ฅผ ํธ์ถํด์ผ ๋ค์ ๋ฏธ๋ค์จ์ด๋ก ๋์ด๊ฐ๋ค. logger๋ express.json, express.urlencoded, cookieParser, express.static ๋ชจ๋ ๋ด๋ถ์ ์ผ๋ก๋ next()๋ฅผ ํธ์ถํ๋ฏ๋ก ๋ค์ ๋ฏธ๋ค์จ์ด๋ก ๋์ด๊ฐ ์ ์๋ค. next()๋ ๋ฏธ๋ค์จ์ด์ ํ๋ฆ์ ์ ์ดํ๋ ํต์ฌ์ ์ธ ํจ์์ด๋ค.
ํ์ธ์ ์ํด next()๋ฅผ ๋นผ๋ณด์.



์ฌ์คํ ํ ๋ค์ ์ ์ํ๋ฉด ์๋ฌด๋ฐ ์๋ต์ด ์๋ค. ๋ธ๋ผ์ฐ์ ์์๋ ๊ณ์ ๋ก๋ฉ ํ์๊ฐ ๋ฌ๋ค. next()๋ฅผ ๋ฃ์ง ์์ ์ปค์คํ ๋ฏธ๋ค์จ์ด์์ ์์ฒญ์ ํ๋ฆ์ด ๋๊ฒจ๋ฒ๋ฆฐ ๊ฒ์ด๋ค.
next() ํจ์์๋ ๋ช ๊ฐ์ง ๊ธฐ๋ฅ์ด ๋ ์๋ค. ์ธ์์ ์ข ๋ฅ๋ก ๊ธฐ๋ฅ์ด ๊ตฌ๋ถ๋๋ค. ์ธ์๋ฅผ ์๋ฌด๊ฒ๋ ๋ฃ์ง ์์ผ๋ฉด ๋จ์ํ๊ฒ ๋ค์ ๋ฏธ๋ค์จ์ด๋ก ๋์ด๊ฐ๊ณ , ์ธ์๋ก route๋ฅผ ๋ฃ์ผ๋ฉด ํน์ํ ๊ธฐ๋ฅ์ ํ๋ค. (์ถํ ๋ค๋ฃฐ ์์ ) route ์ธ์ ๋ค๋ฅธ ๊ฐ์ ๋ฃ์ผ๋ฉด ๋ค๋ฅธ ๋ฏธ๋ค์จ์ด๋ ๋ผ์ฐํฐ๋ฅผ ๊ฑด๋๋ฐ๊ณ ๋ฐ๋ก ์๋ฌ ํธ๋ค๋ฌ๋ก ์ด๋ํ๋ค. ๋ฃ์ด์ค ๊ฐ์ ์๋ฌ์ ๋ํ ๋ด์ฉ์ผ๋ก ๊ฐ์ฃผ๋๋ค.
์ต์คํ๋ ์ค๊ฐ ์์ฑํด์ฃผ๋ ์๋ฌ ํธ๋ค๋ง ๋ฏธ๋ค์จ์ด๋ฅผ ๋ณด๋ฉด ์ดํดํ๊ธฐ ์ฝ๋ค. ๊ฐ์ฅ ํํ ์๋ฌ๊ฐ 404 ์๋ฌ์ด๋ค. ๋ผ์ฐํฐ์ ๋ฑ๋ก๋์ง ์๋ ์ฃผ์๋ก ์์ฒญ์ด ๋ค์ด์ฌ ๋ ๋ฐ์ํ๋ค. ์ด ๊ฒฝ์ฐ์๋ 404 NOT FOUND ์ํ ์ฝ๋๋ฅผ ์๋ตํด์ฃผ์ด์ผ ํ๋ค.

๋ผ์ฐํฐ ๋ค์์ ๋์ค๋ ์ด ๋ถ๋ถ์ด 404 ์๋ฌ๋ฅผ ๋ง๋ค์ด๋ด๋ ๋ฏธ๋ค์จ์ด์ด๋ค. ๋ผ์ฐํฐ์์ ์์ฒญ์ด ์ฒ๋ฆฌ๋์ง ์์ผ๋ฉด(์ผ์นํ๋ ์ฃผ์๊ฐ ์๋ค๋ฉด) ์์ฒญ์ ๋ผ์ฐํฐ ๋ค์์ ์์นํ ์ด ๋ฏธ๋ค์จ์ด๋ก ์ค๊ฒ ๋๋ค. http-errors(createError) ํจํค์ง๊ฐ 404 ์๋ฌ๋ฅผ ๋ง๋ค์ด๋ด๊ณ , ์ด ์๋ฌ๋ฅผ next์ ๋ด์ ์๋ฌ ํธ๋ค๋ฌ๋ก ๋ณด๋ด๊ณ ์๋ค. ์๋ฌ ํธ๋ค๋ง ๋ฏธ๋ค์จ์ด๋ ๋ค์๊ณผ ๊ฐ์ด ์๊ฒผ๋ค.

๋ค๋ฅธ ๋ฏธ๋ค์จ์ด์ ๋ค๋ฅด๊ฒ ํจ์์ ๋งค๊ฐ๋ณ์๊ฐ ๋ค ๊ฐ์ด๋ค. req ์ ์ err๋ผ๋ ๋งค๊ฐ๋ณ์๊ฐ ์ถ๊ฐ๋์๋ค. next ํจ์์ ๋ฃ์ด์ค ์ธ์๊ฐ err ๋งค๊ฐ๋ณ์๋ก ์ฐ๊ฒฐ๋๋ค. ์๋ฌ ํธ๋ค๋ง ๋ฏธ๋ค์จ์ด๋ ์ผ๋ฐ์ ์ผ๋ก ๋ฏธ๋ค์จ์ด ์ค ์ ์ผ ์๋์ ์์นํ์ฌ ์์ ์๋ ๋ฏธ๋ค์จ์ด์์ ๋ฐ์ํ๋ ์๋ฌ๋ฅผ ๋ฐ์์ ์ฒ๋ฆฌํ๋ค.
์ด๋ฒ์๋ app.user์ ์์ฉ ๋ฐฉ๋ฒ์ ๋ํด์ ์์๋ณด์. ํ๋์ use์ ๋ฏธ๋ค์จ์ด๋ฅผ ์ฌ๋ฌ ๊ฐ ์ฅ์ฐฉํ ์ ์๋ค. ์์๋๋ก ์คํ๋๋ค.

์ด ์ฑ์ง์ ํ์ฉํ์ฌ Express-generator๊ฐ ์์ฑํ ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ์ด ์ค์ผ ์ ์๋ค.

next๋ฅผ ํธ์ถํ์ง ์์ผ๋ฉด ๋ค์ ๋ฏธ๋ค์จ์ด๋ก ๋์ด๊ฐ์ง ์๋๋ค๋ ์ฑ์ง์ ์ฌ์ฉํด์ ๋ค์๊ณผ ๊ฐ์ ๋ฏธ๋ค์จ์ด๋ ๋ง๋ค ์ ์๋ค.

2. morgan
ํ์ฌ ์ฝ์์ ๋์ค๋ GET / 200 51.267 ms - 1539 ๊ฐ์ ๋ก๊ทธ๋ ๋ชจ๋ morgan ๋ฏธ๋ค์จ์ด์์ ๋์ค๋ ๊ฒ์ด๋ค. ์์ฒญ์ ๋ํ ์ ๋ณด๋ฅผ ์ฝ์์ ๊ธฐ๋กํด์ค๋ค.
morgan ๋ฏธ๋ค์จ์ด๋ ๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉํ๋ค.
...
var logger = require('morgan');
...
app.use(logger('dev'));
...
ํจ์์ ์ธ์๋ก dev ๋์ short, common, combined ๋ฑ์ ์ค ์ ์๋ค. ์ธ์์ ๋ฐ๋ผ ์ฝ์์ ๋์ค๋ ๋ก๊ทธ๊ฐ ๋ค๋ฅด๋ค. dev์ธ ๊ฒฝ์ฐ GET / 200 51.267 ms - 1539 ์ ์๋ฏธ๋ ์์๋๋ก HTTP ์์ฒญ(GET) ์ฃผ์(/) HTTP ์ํ์ฝ๋(200) ์๋ต์๋(51.267ms) - ์๋ต๋ฐ์ดํธ(1539) ์ด๋ค.
๋ณดํต ๊ฐ๋ฐ ์์๋ short๋ dev๋ฅผ ๋ง์ด ์ฐ๊ณ , ๋ฐฐํฌ ์์๋ common์ด๋ combined๋ฅผ ๋ง์ด ์ฌ์ฉํ๋ค.




์ฝ์๋ฟ๋ง ์๋๋ผ ํ์ผ์ด๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ก๊ทธ๋ฅผ ๋จ๊ธธ ์๋ ์๋ค. ์ด๋ฌํ ์์ ์ ํ ๋๋ winston ๋ชจ๋์ ๋ ๋ง์ด ์ฌ์ฉํ๋ค.
3. body-parser
์์ฒญ์ ๋ณธ๋ฌธ์ ํด์ํด์ฃผ๋ ๋ฏธ๋ค์จ์ด์ด๋ค. ๋ณดํต ํผ ๋ฐ์ดํฐ๋ AJAX ์์ฒญ์ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๋ค.
...
var bodyParser = require('body-parser');
...
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false});
...
์ฐ๋ฆฌ๊ฐ ์์ฑํ app.js์์๋ body-parser๋ฅผ ์ฌ์ฉํ์ง ์์๋ค. ์ต์คํ๋ ์ค 4.16.0 ๋ฒ์ ๋ถํฐ body-parser์ ์ผ๋ถ ๊ธฐ๋ฅ์ด ์ต์คํ๋ ์ค์ ๋ด์ฅ๋์๊ธฐ ๋๋ฌธ์ด๋ค. ๊ทธ๋์ body-parser๋ฅผ ์ค์นํ์ง ์๊ณ ๋ ๋ค์๊ณผ ๊ฐ์ด ํ ์ ์์๋ค.

๋จ, body-parser๊ฐ ํ์ํ ๊ฒฝ์ฐ๋ ์๋ค. body-parser๋ JSON๊ณผ URL-encoded ํ์์ ๋ณธ๋ฌธ ์ธ์๋ Raw, Text ํ์์ ๋ณธ๋ฌธ์ ์ถ๊ฐ๋ก ํด์ํ ์ ์๋ค.
Raw๋ ๋ณธ๋ฌธ์ด ๋ฒํผ ๋ฐ์ดํฐ์ผ ๋, Text๋ ๋ณธ๋ฌธ์ด ํ ์คํธ ๋ฐ์ดํฐ์ผ ๋ ํด์ํ๋ ๋ฏธ๋ค์จ์ด์ด๋ค. ์๋น์ค์ ์ ์ฉํ๊ณ ์ถ๋ค๋ฉด body-parser๋ฅผ ์ค์นํ ํ ๋ค์๊ณผ ๊ฐ์ด ์ถ๊ฐํ๋ค.
app.use(bodyParser.raw());
app.use(bodyParser.text());
JSON์ JSON ํ์์ ๋ฐ์ดํฐ ์ ๋ฌ ๋ฐฉ์์ด๊ณ , URL-encoded๋ ์ฃผ์ ํ์์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ด๋ ๋ฐฉ์์ด๋ค. ๋ณดํต ํผ ์ ์ก์ด URL-encoded ๋ฐฉ์์ ์ฃผ๋ก ์ฌ์ฉํ๋ค. urlencoded ๋ฉ์๋๋ฅผ ๋ณด๋ฉด { extended: false }๋ผ๋ ์ต์ ์ด ๋ค์ด ์๋ค. ์ด ์ต์ ์ด false๋ฉด ๋ ธ๋์ querystring ๋ชจ๋์ ์ฌ์ฉํ์ฌ ์ฟผ๋ฆฌ์คํธ๋ง์ ํด์ํ๊ณ , true๋ฉด qs ๋ชจ๋์ ์ฌ์ฉํ์ฌ ์ฟผ๋ฆฌ์คํธ๋ง์ ํด์ํ๋ค. qs ๋ชจ๋์ ๋ด์ฅ ๋ชจ๋์ด ์๋๋ผ npm ํจํค์ง์ด๋ฉฐ, querystring ๋ชจ๋์ ๊ธฐ๋ฅ์ ์กฐ๊ธ ๋ ํ์ฅํ ๋ชจ๋์ด๋ค.
์ด์ ์ POST์ PUT ์์ฒญ์ ๋ณธ๋ฌธ์ ์ ๋ฌ๋ฐ์ผ๋ ค๋ฉด req.on('data')์ req.on('end')๋ก ์คํธ๋ฆผ์ ์ฌ์ฉํด์ผ ํ์๋๋ฐ body-parser๋ฅผ ์ฌ์ฉํ๋ฉด ๊ทธ๋ด ํ์๊ฐ ์๋ค. ์ด ํจํค์ง๊ฐ ๋ด๋ถ์ ์ผ๋ก ๋ณธ๋ฌธ์ ํด์ํด req.body์ ์ถ๊ฐํด์ค๋ค.
์๋ฅผ ๋ค์ด JSON ํ์์ผ๋ก {name: 'zerocho', book: 'nodejs'}๋ฅผ ๋ณธ๋ฌธ์ผ๋ก ๋ณด๋ธ๋ค๋ฉด req.body์ ๊ทธ๋๋ก ๋ค์ด๊ฐ๋ค. URL-encoded ํ์์ผ๋ก name=zerocho&book=nodejs๋ฅผ ๋ณธ๋ฌธ์ผ๋ก ๋ณด๋ธ๋ค๋ฉด req.body์ {name: 'zerocho', book: 'nodejs'}๊ฐ ๋ค์ด๊ฐ๋ค.
body-parser๊ฐ ๋ชจ๋ ๋ณธ๋ฌธ์ ํด์ํด์ฃผ๋ ๊ฒ์ ์๋๋ค. multipart/form-data ๊ฐ์ ํผ์ ํตํด ์ ์ก๋ ๋ฐ์ดํฐ๋ ํด์ํ์ง ๋ชปํ๋ค. ์ด๋ ๋ค๋ฅธ ๋ชจ๋์ ์ฌ์ฉํด์ ํด์ํด์ผ ํ๋ค.
4. cookie-parser
cookie-parser๋ ์์ฒญ์ ๋๋ด๋ ์ฟ ํค๋ฅผ ํด์ํด์ค๋ค.
...
var cookieParser = require('cookie-parser');
...
app.use(cookieParser());
...
ํด์๋ ์ฟ ํค๋ค์ req.cookies ๊ฐ์ฒด์ ๋ค์ด๊ฐ๋ค. ์๋ฅผ ๋ค์ด, name=zerocho ์ฟ ํค๋ฅผ ๋ณด๋๋ค๋ฉด req.cookies๋ { name: 'zerocho' }๊ฐ ๋๋ค.
app.use(cookieparser('secret code');
์ด์ ๊ฐ์ด ์ฒซ ๋ฒ์งธ ์ธ์๋ก ๋ฌธ์์ด์ ๋ฃ์ด์ค ์ ์๋ค. ์ด์ ์ฟ ํค๋ค์ ์ ๊ณตํ ๋ฌธ์์ด๋ก ์๋ช ๋ ์ฟ ํค๊ฐ ๋๋ค. ์๋ช ๋ ์ฟ ํค๋ ํด๋ผ์ด์ธํธ์์ ์์ ํ์ ๋ ์๋ฌ๊ฐ ๋ฐ์ํ๋ฏ๋ก ํด๋ผ์ด์ธํธ์์ ์ฟ ํค๋ก ์ํํ ํ๋์ ํ๋ ๊ฒ์ ๋ฐฉ์งํ ์ ์๋ค.
5. static
static ๋ฏธ๋ค์จ์ด๋ ์ ์ ์ธ ํ์ผ๋ค์ ์ ๊ณตํ๋ค. ์ต์คํ๋ ์ค๋ฅผ ์ค์นํ๋ฉด ๋ฐ๋ผ์ค๋ฏ๋ก ๋ฐ๋ก ์ค์นํ ํ์๋ ์๋ค.
...
app.use(express.static(path.join(__dirname, 'public')));
...
ํจ์์ ์ธ์๋ก ์ ์ ํ์ผ๋ค์ด ๋ด๊ฒจ ์๋ ํด๋๋ฅผ ์ง์ ํ๋ฉด ๋๋ค. ํ์ฌ public ํด๋๊ฐ ์ง์ ๋์ด ์๋ค. public/stylesheets/style.css๋ http://localhost:3000/stylesheets/style.css๋ก ์ ๊ทผํ ์ ์๋ค.
์ค์ ์๋ฒ์ ํด๋ ๊ฒฝ๋ก์๋ public์ด ๋ค์ด ์์ง๋ง, ์์ฒญ ์ฃผ์์๋ public์ด ๋ค์ด ์์ง ์๋ค๋ ์ ์ ์ฃผ๋ชฉํด์ผ ํ๋ค. ์๋ฒ์ ํด๋ ๊ฒฝ๋ก์ ์์ฒญ ๊ฒฝ๋ก๊ฐ ๋ค๋ฅด๋ฏ๋ก ์ธ๋ถ์ธ์ด ์๋ฒ์ ๊ตฌ์กฐ๋ฅผ ์ฝ๊ฒ ํ์ ํ ์ ์๋ค. ์ด๋ ๋ณด์์ ํฐ ๋์์ด ๋๋ค.
๋ํ, ์ ์ ํ์ผ๋ค์ ์์์ ์ ๊ณตํด์ฃผ๋ฏ๋ก ์ด์ ์์ ์ฒ๋ผ fs.readFile๋ก ํ์ผ์ ์ง์ ์ฝ์ด์ ์ ์กํ ํ์๊ฐ ์๋ค.
app.use('/img', express.static(path.join(__dirname, 'public')));
์ด์ ๊ฐ์ด ์ ์ ํ์ผ์ ์ ๊ณตํ ์ฃผ์๋ฅผ ์ง์ ํ ์๋ ์๋ค. public ํด๋ ์์ abc.png๊ฐ ์๋ค๊ณ ๊ฐ์ ํ๋ฉด ์์ /img ๊ฒฝ๋ก๋ฅผ ๋ถ์ธ http://localhost:3000/img/abc.png ์ฃผ์๋ก ์ ๊ทผํ ์ ์๋ค.
static ๋ฏธ๋ค์จ์ด๋ ์์ฒญ์ ๋ถํฉํ๋ ์ ์ ํ์ผ์ ๋ฐ๊ฒฌํ ๊ฒฝ์ฐ ์๋ต์ผ๋ก ํด๋น ํ์ผ์ ์ ์กํ๋ค. ์ด ๊ฒฝ์ฐ ์๋ต์ ๋ณด๋์ผ๋ฏ๋ก ๋ค์์ ๋์ค๋ ๋ผ์ฐํฐ๊ฐ ์คํ๋์ง ์๋๋ค. ๋ง์ฝ ํ์ผ์ ์ฐพ์ง ๋ชปํ๋ฉด ์์ฒญ์ ๋ผ์ฐํฐ๋ก ๋๊ธด๋ค.
์ด๋ ๊ฒ ์์ฒด์ ์ผ๋ก ์ ์ ํ์ผ ๋ผ์ฐํฐ ๊ธฐ๋ฅ์ ์ํํ๋ฏ๋ก ์ต๋ํ ์์ชฝ์ ๋ฐฐ์นํ๋ ๊ฒ์ด ์ข๋ค. ๊ทธ๋์ผ ์๋ฒ๊ฐ ์ธ๋ฐ์๋ ๋ฏธ๋ค์จ์ด ์์ ์ ํ๋ ๊ฒ์ ๋ง์ ์ ์๋ค.
๊ธฐ์กด ์ฝ๋์์๋ morgan, json, urlencoded, cookie-parser ๋ฏธ๋ค์จ์ด๋ฅผ ๊ฑฐ์ณ์ผ static ๋ฏธ๋ค์จ์ด์ ๋๋ฌํ๋ค. ์์ฒญ์ ๊ธฐ๋กํ๋ morgan์ ์ ์ธํ๊ณ ์ ์ ํ์ผ์ ์ ๊ณตํ๋ ๋ฐ ์ํฅ์ ๋ผ์น์ง ์๋ json, urlencoded, cookie-parser๋ฅผ ๊ฑฐ์น๋ ๊ฒ์ ๋ญ๋น์ด๋ค. ๋ฐ๋ผ์ ์์๋ฅผ ๋ฐ๊ฟ์ฃผ๋ ๊ฒ์ด ์ข๋ค. ์ฐธ๊ณ ๋ก ์๋น์ค์ ๋ฐ๋ผ ์ฟ ํค ๊ฐ์ ๊ฒ์ด ์ ์ ํ์ผ์ ์ ๊ณตํ๋ ๋ฐ ์ํฅ์ ๋ผ์น ์๋ ์๋ค. ๊ทธ๋ฌ๋ฏ๋ก ์์ ์ ์๋น์ค์ ๋ง๋ ์์น๋ฅผ ์ ํํด์ผ ํ๋ค.
6. express-session
์ธ์ ๊ด๋ฆฌ์ฉ ๋ฏธ๋ค์จ์ด์ด๋ค. ๋ก๊ทธ์ธ ๋ฑ์ ์ด์ ๋ก ์ธ์ ์ ๊ตฌํํ ๋ ๋งค์ฐ ์ ์ฉํ๋ค. express-generator๋ก๋ ์ค์น๋์ง ์์ผ๋ฏ๋ก ๋ค์๊ณผ ๊ฐ์ด ์ง์ ์ค์นํด์ผ ํ๋ค.

์ค์น ํ app.js์ express-session์ ์ฐ๊ฒฐํ๋ค.
...
var session = require('express-session');
...
app.use(cookieParser());
app.use(session({
resave: false,
saveUninitialized: false,
secret: 'secret code',
cookie: {
httpOnly: true,
secure: false
}
}));
...
express-session 1.5 ๋ฒ์ ์ด์ ์๋ ๋ด๋ถ์ ์ผ๋ก cookie-parser๋ฅผ ์ฌ์ฉํ๊ณ ์์ด์ cookie-parser ๋ฏธ๋ค์จ์ด๋ณด๋ค ๋ค์ ์์นํด์ผ ํ์ง๋ง, 1.5 ๋ฒ์ ์ดํ๋ถํฐ๋ ์ฌ์ฉํ์ง ์๊ฒ ๋์ด ์์๊ฐ ์๊ด ์์ด์ก๋ค. ๊ทธ๋๋ ํ์ฌ ์ด๋ค ๋ฒ์ ์ ์ฌ์ฉํ๊ณ ์๋์ง ๋ชจ๋ฅธ๋ค๋ฉด cookie-parser ๋ฏธ๋ค์จ์ด ๋ค์ ๋๋ ๊ฒ์ด ์์ ํ๋ค.
express-session์ ์ธ์๋ก ์ธ์ ์ ๋ํ ์ค์ ์ ๋ฐ๋๋ค.
- resave : ์์ฒญ์ด ์์ ๋ ์ธ์ ์ ์์ ์ฌํญ์ด ์๊ธฐ์ง ์๋๋ผ๋ ์ธ์ ์ ๋ค์ ์ ์ฅํ ์ง์ ๋ํ ์ค์ ์ด๋ค.
- saveUninitialized : ์ธ์ ์ ์ ์ฅํ ๋ด์ญ์ด ์๋๋ผ๋ ์ธ์ ์ ์ ์ฅํ ์ง์ ๋ํ ์ค์ ์ด๋ค. ๋ณดํต ๋ฐฉ๋ฌธ์๋ฅผ ์ถ์ ํ ๋ ์ฌ์ฉ๋๋ค.
- secret : ํ์ ํญ๋ชฉ์ผ๋ก cookie-parser์ ๋น๋ฐํค์ ๊ฐ์ ์ญํ ์ ํ๋ค. express-session์ ์ธ์ ๊ด๋ฆฌ ์ ํด๋ผ์ด์ธํธ์ ์ฟ ํค๋ฅผ ๋ณด๋ธ๋ค. ์ด๋ฅผ ์ธ์ ์ฟ ํค๋ผ๊ณ ๋ถ๋ฅธ๋ค. ์์ ํ๊ฒ ์ฟ ํค๋ฅผ ์ ์กํ๋ ค๋ฉด ์ฟ ํค์ ์๋ช ์ ์ถ๊ฐํด์ผ ํ๊ณ , ์ฟ ํค๋ฅผ ์๋ช ํ๋ ๋ฐ secret์ ๊ฐ์ด ํ์ํ๋ค. cookie-parser์ secret๊ณผ ๊ฐ๊ฒ ์ค์ ํด์ผ ํ๋ค.
- cookie : ์ธ์ ์ฟ ํค์ ๋ํ ์ค์ ์ด๋ค. maxAge, domain, path, expires, sameSite, httpOnly, secure ๋ฑ ์ผ๋ฐ์ ์ธ ์ฟ ํค ์ต์ ์ด ๋ชจ๋ ์ ๊ณต๋๋ค.
express-session์ req ๊ฐ์ฒด ์์ req.session ๊ฐ์ฒด๋ฅผ ๋ง๋ ๋ค. ์ด ๊ฐ์ฒด์ ๊ฐ์ ๋์ ํ๊ฑฐ๋ ์ญ์ ํด์ ์ธ์ ์ ๋ณ๊ฒฝํ ์ ์๋ค. ๋์ค์ ์ธ์ ์ ํ ๋ฒ์ ์ญ์ ํ๋ ค๋ฉด req.session.destroy() ๋ฉ์๋๋ฅผ ํธ์ถํ๋ฉด ๋๋ค. ํ์ฌ ์ธ์ ์ ์์ด๋๋ req.sessionId๋ก ํ์ธํ ์ ์๋ค.
7. connect-flash
์๋์ ์ผ๋ก ์ค์๋๊ฐ ๋จ์ด์ง๋ ๋ฏธ๋ค์จ์ด์ด๋ค. ํ์ง๋ง ์ผํ์ฑ ๋ฉ์์ง๋ค์ ์น ๋ธ๋ผ์ฐ์ ์ ๋ํ๋ผ ๋ ์ข๋ค. express-session๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก ์ง์ ์ค์นํด์ฃผ์ด์ผ ํ๋ค.

connect-flash ๋ฏธ๋ค์จ์ด๋ cookie-parser์ express-session์ ์ด์ฉํ๋ฏ๋ก ์ด๋ค๋ณด๋ค๋ ๋ค์ ์์นํด์ผ ํ๋ค.
...
var session = require('express-session');
var flash = require('connect-flash');
...
app.use(session({
resave: false,
saveUninitialized: false,
secret: 'secret code',
cookie: {
httpOnly: true,
secure: false
}
}));
app.use(flash());
...
flash ๋ฏธ๋ค์จ์ด๋ req ๊ฐ์ฒด์ req.flash ๋ฉ์๋๋ฅผ ์ถ๊ฐํ๋ค. req.flash(ํค, ๊ฐ)์ผ๋ก ํด๋น ํค์ ๊ฐ์ ์ค์ ํ๊ณ , req.flash(ํค)๋ก ํด๋น ํค์ ๋ํ ๊ฐ์ ๋ถ๋ฌ์จ๋ค.

์ผํ์ฑ ๋ฉ์์ง๋ผ๋ ์ฑ์ง์ ์ด์ฉํ์ฌ ๋ก๊ทธ์ธ ์๋ฌ๋ ํ์๊ฐ์ ์๋ฌ ๊ฐ์ ์ผํ์ฑ ๊ฒฝ๊ณ ๋ฉ์์ง๋ flash ๋ฏธ๋ค์จ์ด๋ก ๋ณด๋ด๋ฉด ์ข๋ค.