express, session , cookie

nn·2023년 1월 7일

세션 : 서버에 저장
쿠키 : 브라우저에 저장

세션은 서버가 생성하여 클라이언트에 sid라는 세션 아이디를 전송한다.
세션은 유저 정보같은 민감한 정보를 가지고 있으므로 키가 되는 sid만 클라이언트에 전송하여 보안을 강화한것이다.

클라이언트가 서버로 요청을 보낼때 서버는 이 sid 쿠키로부터 사용자의 로그인 상태등을 유지할 수 있다.

express에서는 express-session을 사용해 세션을 관리할 수 있다.

  req.session.user = result.user;
  await this.sessionStore.saveSession(req);

user라는 키에 유저 정보를 저장하고, session을 저장했다.

export class SessionStore implements ISessionStore {
  async saveSession(req: Request): Promise<void> {
    return new Promise<void>((resolve, reject) => {
      req.session.save((err) => {
        if (err) {
          reject(err);
        } else {
          resolve();
        }
      });
    });
  }

session data가 변경되면 자동으로 저장이 되므로 req.session.save로 직접 저장하지 않아도 괜찮다.

세션삭제

보통 로그아웃을 하면 세션을 삭제해 로그인 유지를 푼다.

req.session.destroy()

destroy함수를 통해 세션을 제거할 수 있다.

나는 redis에 세션을 저장하고 있어서 redis에서 세션을 제거했다.


  public logout: AsyncRequestHandler = async (req, res) => {
    await RedisHandler.findSession(req.body.sessionID);
    ...생략

   await RedisHandler.deleteSession(req.body.sessionID);
 static async deleteSession(key: string): Promise<void> {
   const sessionKey = `${RedisHandler.SESSION_PREFIX}${key}`;
   await redisClient.del(sessionKey);
 }

options

세션 옵션에는 다음과 같은 것이 있다.


export const sessionConfig = {
 store: new RedisStore({
   client: redisClient,
   ttl: REDIS_TIME_TO_LIVE,
   prefix: "session:",
 }),
 cookie: {
   httpOnly: true, // 자바스크립트를 통해 세션 쿠키를 사용할 수 없도록 함 localhost, ip일때는 쓰면 안된다. 저장안됨
   sameSite: "none",
   secure: true,
   domain: ".acoha.store",
 },
 credentials: true,
 secret: SESSION_SECRET,
 resave: false, //true -> 모든 요청마다 세션을 다시 저장한다. 
 saveUninitialized: false,//세션에 저장할 내용이 없으면 저장하지 않음
} as SessionOptions;

store

세션을 어디에 저장할 것인지 명시한다.
나는 redis에 저장했고,
ttl은 세션의 유지 시간이다.
prefix를 통해 저장된 정보가 session임을 알 수 있도록 설정했다.

sid에 대한 설정이다.
디폴트는 다음과 같다.
{ path: '/', httpOnly: false, secure: false, maxAge: null }

  • path : 쿠키가 전송될 경로
  • httpOnly : document.cookie를 통한 쿠키 접근을 막는다.
    쿠키는 클라이언트에서 조회가 되므로 자바스크립트로 쿠키를 가로챌수있다. (CSS)
    그러므로 httpOnly를 true로 설정해 공격을 방지 할 수 있다.
  • secure : https 프로토콜을 사용하지 않은 http통신에서는 쿠키를 전송하지 않는다.
  • domain : 쿠키가 유효한 사이트를 설정
  • sameSite
    - none : 항상 전송 (sameSite를 none으로 하는 경우엔 secure 가 true여야한다. )
    - stric : 크로스 사이트 전송(다른 도메인) 일 때는 전송되지 않음
    - lax : 같은 웹 사이트일 경우 전송, 이 외에는 Top Level Navigation(웹 페이지 이동)과, "안전한" HTTP 메서드 요청의 경우에만 전송
    즉, get 요청인경우엔 전송되나, post, delete요청과 같이 서버의 상태를 바꿀수 있는 요청에는 전송이 되지 않는다.

credentials

cors는 보안상 정책으로 동일 출처인 경우에만 요청이 가능하게 하는 것이다.
다른 출처도 접근을 허용하기위해선 cors 옵션에 허용할 도메인을 명시해주어야한다.
이때 같은 보안상의 이유로 쿠키도 요청을 막고있다.
쿠키를 허용해주기 위해서 서버와 클라이언트 모두 credentials을 true로 해주어야한다.

profile
내가 될 거라고 했잖아

0개의 댓글