본문 바로가기
공부/express

[Express] Redis 클라우드 서버를 세션 스토리지로 사용하기 (redislabs)

by 웅대 2024. 5. 26.
728x90
반응형

https://growth-coder.tistory.com/278

 

[Express] 쿠키 세션 방식으로 로그인 구현

이번 포스팅에서는 쿠키, 세션 방식으로 로그인을 구현해보려고 한다. 세팅 패키지를 설치하자. npm install express express-session bcrypt dotenv passport passport-local mongoose express : express 서버express-session :

growth-coder.tistory.com

 

이전 포스팅에서 쿠키, 세션 방식으로 로그인을 구현했었다.

 

이 때는 세션을 단순하게 메모리에 저장을 했었는데 이번 포스팅에서는 redislabs라는 redis 클라우드 서비스를 사용해서 메모리가 아닌 별도 저장소에 저장하려고 한다.

 

먼저 클라우드 서비스를 통해 세션 저장소를 서버로부터 분리하는 것의 장점을 알아보자.

 

메모리가 아닌 별도 저장소를 사용하기 때문에 세션을 안전하게 관리할 수 있다.

 

만약 별도로 저장소를 두지 않는다면 기본적으로 메모리에 세션이 저장된다.

 

메모리에 저장되는 데이터는 휘발성이기 때문에 서버를 재시작하면 그 안의 데이터는 모두 날라간다.

 

그에 비해 redislabs와 같은 클라우드 서비스를 사용하면 외부에서 관리되는 redis 데이터베이스 안에 데이터를 저장하기 때문에 서버와 독립적으로 데이터를 관리할 수 있다.

 

분산 시스템에 유리하다

 

단일 서버로 운영 중이다가 서버의 트래픽이 많아지면 서버를 여러 개 만들고 트래픽을 적절하게 분산하는 로드밸런싱을 사용하게 될 수 있다.

 

혹은 Node.js에서는 클러스터링을 사용해서 서버를 여러 개 띄우게 될 수도 있다.

 

만약 서버 메모리에 세션을 저장한다면 각 서버마다 세션이 하나씩 존재하기 때문에 세션 정보를 공유할 수가 없다.

 

만약 로드 밸런서가 로그인 요청을 1번 서버로 보낸다면 1번 서버 메모리에 세션 정보가 저장될 것이다.

 

그리고 로드 밸런서가 인증이 필요한 요청을 2번 서버로 보낸다면 2번 서버 메모리에는 세션 정보가 없기 때문에 요청을 거절할 것이다.

 

이 때 클라우드 서비스를 이용해서 세션 정보를 외부 데이터베이스에 저장한다면 모든 서버가 하나의 데이터베이스에 세션 정보를 저장하고 조회하기 때문에 세션 정보를 모든 서버가 공유할 수 있다.

 

이 외에도 클라우드 서비스를 사용해서 세션 정보를 저장하면 서버의 부담을 줄일 수도 있고 여러 장점들이 존재한다.

 

redislabs 사용 이유

먼저 세션을 저장할 데이터베이스로 redis를 선택한 이유는 NoSQL임과 동시에 인 메모리 데이터베이스이기 때문에 속도가 관계형 데이터베이스에 비해 빠르다.

 

그리고 우리가 세션에 저장할 데이터는 유저 아이디 하나 뿐이기 때문에 큰 용량이 필요하지도 않다.

 

redis를 사용할 수 있는 클라우드 서비스도 다양한데 대표적으로 aws의 ElasticCache 서비스가 있다.

 

처음에는 ElasticCache를 사용하려고 했으나 기본적으로 aws 서비스의 같은 vpc 내부에서만 redis에 접근할 수 있었다.

 

즉 로컬에서 직접 접근하기 위해서는 까다로운 과정을 거쳐야 했기에 외부에서 쉽게 접근이 가능한 redislabs를 선택했다.

 

물론 aws EC2를 사용하여 서버를 배포할 때는 ElasticCache를 사용하는 것이 보안에 좋을 것이다.

 

세션 스토리지로 redis 사용

그러면 이제 Express 서버에서 redislabs 클라우드 서비스를 사용해서 세션 정보를 redis에 저장해보자.

 

redislabs에 가입해서 redis 데이터베이스를 생성해보자.

 

<가입 링크>

https://app.redislabs.com/#/

 

클라우드는 그냥 aws를 선택하고 region은 한국이 없어서 일본을 선택했다.

 

Let's start free 버튼을 누르면 데이터베이스가 생성된 것을 확인할 수 있다.

 

이제 express-session의 store에 redis를 등록해보자.

 

위에서 생성된 무료 데이터베이스 정보를 확인하자.

 

사용할 정보는 public endpoint와 password이다.

 

 

해당 정보를 dotenv에 저장하자

 

<.env>

# redis session storage
REDIS_ENDPOINT=redis-12337.c290.ap-northeast-1-2.ec2.redns.redis-cloud.com:12337
REDIS_PASSWORD=ajVcP30jLbapqU5N4ouO3NFWUIENmA8M

 

express-session과 redis를 연결하기 전 기본적인 메모리 스토어를 사용할 때의 코드를 보자.

 

<index.js>

.
.
.
const app = express()
const session = require('express-session')
app.use(session({
    cookie: {
        path: "/", // 쿠키 저장 경로.
        httpOnly: true, // 클라이언트가 자바스크립트를 통해 쿠키 접근 불가.
        secure: false, // https에서만 사용 여부. 로컬에서 http로 테스트 할 예정이므로 false.
        maxAge: null // 만료 시간. null이면 무한
    },
    secure: false, // https에서만 사용 여부. 로컬에서 http로 테스트 할 예정이므로 false.
    secret: process.env.SECRET_KEY, // 시크릿 키. 
    saveUninitialized: false, // 세션이 변경되지 않았을 때 세션은 초기화 되지 않지만 true로 두면 초기화 됨. 
    resave: false // 변경 사항이 없어도 항상 세션을 저장할지
}))
.
.
.

 

이제 redis 스토어로 변경해보자.

 

필요한 패키지는 redis와 connect-redis이다. 설치하자.

 

  • redis : redis 연결을 도와주는 패키지
  • connect-redis : express-session이 필요하고 세션 스토리지를 redis로 사용할 수 있게 도와주는 패키지
npm i redis connect-redis

 

이제 redis를 연결해보자.

.
.
.
const app = express()
app.use(express.json())
const dotenv = require('dotenv')
const session = require('express-session')
const redis = require('redis')
const RedisStore = require('connect-redis').default
const redisClient = redis.createClient({
    url: `redis://${process.env.REDIS_ENDPOINT}`,
    password: process.env.REDIS_PASSWORD
})
redisClient.connect().catch(console.error)
app.use(session({
    cookie: {
        path: "/", // 쿠키 저장 경로.
        httpOnly: true, // 클라이언트가 자바스크립트를 통해 쿠키 접근 불가.
        secure: false, // https에서만 사용 여부. 로컬에서 http로 테스트 할 예정이므로 false.
        maxAge: null // 만료 시간. null이면 무한
    },
    secure: false, // https에서만 사용 여부. 로컬에서 http로 테스트 할 예정이므로 false.
    secret: process.env.SECRET_KEY, // 시크릿 키. 
    saveUninitialized: false, // 세션이 변경되지 않았을 때 세션은 초기화 되지 않지만 true로 두면 초기화 됨. 
    resave: false, // 변경 사항이 없어도 항상 세션을 저장할지
    store: new RedisStore({client: redisClient})
}))
.
.
.

 

  1. redis 패키지의 createClient 메소드를 사용하여 엔드포인트와 비밀번호를 넣어서 redisClient를 생성한다.
  2. redisClient의 connect 메소드를 사용해서 연결한다.
  3. connect-redis의 RedisStore 인스턴스를 생성하고 그 안에 redisClient를 넣어준다.
  4. express-session의 store에 RedisStore를 넣어준다.

이제 로그인을 시도해보자.

 

두 개의 계정으로 로그인을 시도한다면 redis에 2개의 세션이 저장되어야 한다.

 

redislabs의 데이터베이스에 접근을 해야 하는데 redis-cli를 사용하여 접근해보자.

 

먼저 redis-cli를 설치해보자.

 

npm i redis-cli

 

redislabs에서 데이터베이스에 접속해서 오른쪽의 connect 버튼을 눌러보자.

 

 

다양한 방법을 알려주는데 그 중 redis-cli를 선택하면 명령어가 나온다. 이 명령어를 붙여준다.

 

글로벌로 redis-cli를 설치했다면 위 명령어를 복사하면 되지만 그러지 않았다면 앞에 npx를 붙여주자.

 

redis에 접속했다면 keys * 명령어를 입력해보자.

 

두 개의 계정이 로그인 했다면 두 개의 세션이 생성되어 있어야 한다.

 

성공적으로 생성되었다.

 

get [키 이름]을 통해 세션 정보도 확인해보자.

 

유저 아이디가 제대로 저장되었다.

 

이제 서버를 재시작해도 로그인 정보가 유지된다.

728x90
반응형

댓글