์ธ์ ํด๋ฌ์คํฐ๋ง์ ์ํด์ Redis๋ฅผ ์คํ ์ด๋ก ๊ด๋ฆฌํ๋ ์ธ์ ์ ๊ตฌํํด ๋ณด์.ย
connect-redis๋ฅผ ์ด์ฉํ๋ฉด ์ฌํํ๊ฒ ๊ตฌ์ถ์ด ๊ฐ๋ฅํ๋ค.ย
ํ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์๋์ ๊ฐ๋ค.
morgan์ ์ค์นํ ์ด์ ๋ ๋ธ๋ผ์ฐ์ ์ ์ฟ ํค๊ฐ์ด ์ด๋ป๊ฒ ์ฌ๋ผ์ค๋์ง ํ์ธํ๊ธฐ ์ํด์๋ค.ย
$ npm install express express-session morgan redis connect-redis
์ธ์ ์ ๋ณด๋ฅผ ๊ฐ์ง๋ Redis๋ฅผ ๊ตฌ์ถํด๋ณด์.ย
์๋์ ๊ฐ์ด docker๋ก ๊ตฌ์ฑํด๋ณด์. ํจ์ค์๋๋ฅผ ์ง์ ํ์์ ํ์ธํ์.ย
// docker-compose.yml
services:
redis:
image: docker.io/bitnami/redis:7.4
environment:
# ALLOW_EMPTY_PASSWORD is recommended only for development.
- ALLOW_EMPTY_PASSWORD=no
- REDIS_PASSWORD=passw0rd
- REDIS_DISABLE_COMMANDS=FLUSHDB,FLUSHALL
ports:
- '6379:6379'
volumes:
- 'redis_data:/bitnami/redis/data'
volumes:
redis_data:
driver: local
express-session์ผ๋ก ๊ตฌ์ฑํ๋ค.ย
store์ ๋ณด๋ง redis๋ก ์ ๊ณตํ๋ฉด ๋๊ธฐ ๋๋ฌธ์ ๋ค๋ฅธ mysql ๋ฐ ๋ค๋ฅธ ์คํ ์ด๋ก ๋ฐ๊พธ๋ ๊ฒ๋ ์ฝ๊ฒ ๊ฐ๋ฅํ๋ค.ย
redisClient๋ฅผ ๊ฐ์ง๋ RedisStore๋ฅผย ์ธ์ ์ ํ๋ผ๋ฉํฐ๋ก ์ฃผ์ ๋๋ ๋ถ๋ถ์ด ํต์ฌ์ด๋ค.ย
import express from 'express';
import session from 'express-session';
import morgan from 'morgan';
import {RedisStore} from "connect-redis"; // ์ต์ ๋ฒ์ ์ `.default` ํ์
import { createClient } from 'redis';
const redisClient = createClient({
host: '127.0.0.1',
port: 6379,
password: 'passw0rd', // Redis ๋น๋ฐ๋ฒํธ
});
redisClient.on('connect', () => console.log('๐ Redis ์ฐ๊ฒฐ ์๋ฃ!'));
redisClient.on('error', (err) => console.error('โ Redis ์ค๋ฅ:', err));
redisClient.on('end', () => console.log('Redis ์ฐ๊ฒฐ ์ข
๋ฃ') );
redisClient.connect();
let redisStore = new RedisStore({client:redisClient,prefix: 'oauth.session:'});
const app = express();
app.use(session({
store: redisStore,
secret: 'your-secret-key', // ํ์!
resave: false,
saveUninitialized: false,
cookie: { secure: false, maxAge: 1000 * 60 * 60 }
}));
// ๋ก๊น
morgan.token('headers', (req) => JSON.stringify(req.headers));
app.use(morgan(':method :url :status :res[content-length] - :response-time ms :headers'));
app.use(express.json());
app.get('/',(req,res)=>{
res.send("Hello, World!!");
});
app.get('/session',(req,res)=>{
if (!req.session.views) req.session.views = 1;
else req.session.views++;
res.send(`Session View Cnt ${req.session.views}`);
});
app.listen(8000,()=>{
console.log("Server listening in http://localhost:8000")
});
curl ๋ช ๋ น์ด๋ฅผ ํตํด์ session์ ๊ฐ์ ์์ฑํด ๋ณธ๋ค.ย
$ curl http://localhost:8000/session
Session View Cnt 1
$
Redis์ ์ ์ํด์ session์ ๋ณด๊ฐ Redis์ ์ ์ฅ๋์๋์ง ํ์ธํด ๋ณธ๋ค.
์๋์ ๊ฐ์ด ์ธ์ ์ด ์ ์ฅ๋์๊ณ ๋ง๋ฃ์๊ฐ์ด ์ง๋๋ฉด ์ธ์ ์ด ์ฌ๋ผ์ง ๊ฒ์ด๋ค.ย
127.0.0.1:6379> keys *
1) "oauth.session:V3laDuWJRSLi0gX9xGzpEemdIi-y_YVC"
127.0.0.1:6379>
127.0.0.1:6379> get oauth.session:V3laDuWJRSLi0gX9xGzpEemdIi-y_YVC
"{\"cookie\":{\"originalMaxAge\":3600000,\"expires\":\"2025-02-23T08:04:25.048Z\",\"secure\":false,\"httpOnly\":true,\"path\":\"/\"},\"views\":13}"
127.0.0.1:6379>
Express ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ์ธ์ ์คํ ์ด๋ฅผ Redis๋ฅผ ๊ฐ์ง๋๋ก ๊ตฌํํด ๋ณด์๋ค. ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํํ์ฅํ์ฌ ๊ตฌ์ฑ์ ํ๋๋ผ๋ ๋์ผํ ์ธ์ ์คํ ์ด์ ์กฐํ,์ ์ฅ์ ํ๊ธฐ ๋๋ฌธ์ ์ธ์ ํฌ๋ฌ์คํฐ๋ง์ด ๊ตฌํ๋์ด์ง๋ค.