Iron sessions

With·2022년 3월 1일
0

Next Backend

목록 보기
4/6

Iron Sessions 이란?

서명, 암호화된 쿠기를 사용하는 Node.js stateless 세션도구

  1. payload 생성
  2. payload를 암호화한다.
  3. 쿠키로 전송 (쿠키는 client에서 server로 요청을 보낼때 마다 같이 전송됨)
  4. 쿠키를 받아 복호화하고 payload 조회

JWT와 다르다. JWT는 payload가 암호화 되지 않는다.

장점

  1. JWT가 아니다 = 암호화 되어 유저가 정보를 확인할 수 없다.
  2. 세션을 위한 백엔드를 구축하지 않아도 된다.
  3. 유용한 helper function = withIronSesstionApiRoute이 있다.
// withIronSesstionApiRoute로 handler를 감싸준다
export default withIronSesstionApiRoute(
  // 👇 handler
  async function loginRoute(req, res) {
    req.session.user = {
      id: 230,
      admin : true,
    };
    await req.session.save();
    res.send({ok: true});
  }
)

// Promise를 return 한다.
  • withIronSesstionApiRoute 를 통해서 감싸진 handler의 request객체에 sesstion 객체를 담아서 쿠키로 보낸다.

withHandler와 같이 사용했을 때

export default withIronSesstionApiRoute(withHandler("POST", handler), {
  cookieName : "carrotsession",
  password : "thisisthesomethingpassword" //password를 통해서 쿠키를 암호화/복호화한다.
});

useCase

import { withIronSessionApiRoute } from "iron-session/next";
import { NextApiRequest, NextApiResponse } from "next";
import withHandler, { ResponseType } from "@libs/server/withHandler";
import client from "@libs/server/client";

// session 안에서 임의로 생성되는 객체들에 대한 타입을 해준다.
declare module "iron-session" {
  interface IronSessionData {
    user?: {
      id: number;
    };
  }
}

// User의 phone 번호를 입력 받고, 해당 유저가 존재하는 유저인지 확인한다.
// 만약 해당 유저가 존재한다면 exists 라는 session에 해당 유저의 정보를 삽입한다.
async function handler(
  req: NextApiRequest,
  res: NextApiResponse<ResponseType>
) {
  const { token } = req.body; // client에서 전송된 정보
    
  // prisma를 통해 db에서 데이터르 조회한다.
  const exists = await client.token.findUnique({
    where: {
      payload: token,
    },
    include: { user: true }, // exists에 user 정보를 삽입, db에서 relation이 연결되어 있어야 가능
  });

  if (!exists) return res.status(404).end();

  // session에 user의 id를 저장한다.
  // session에 user와 같이 임의로 이름을 정할 수 있다
  req.session.user = {
    id: exists.userId,
  };
  await req.session.save(); // 생성한 session을 저장하는 명령
  res.status(200).end();
}

export default withIronSessionApiRoute(withHandler("POST", handler), {
  cookieName: "carrotsession",
  password: "thisisthesomethingpassword",
});

결과로 cookie에 exists가 저장된다. 그리고 cookie는 client에서 요청을 보낼때마다 같이 전송되고, 서버에서는 cookie를 받아 복호화 후 payload의 내용을 확인 할 수 있다.

import { withIronSessionApiRoute } from "iron-session/next";
import { NextApiRequest, NextApiResponse } from "next";
import withHandler, { ResponseType } from "@libs/server/withHandler";
import client from "@libs/server/client";

declare module "iron-session" {
  interface IronSessionData {
    user?: {
      id: number;
    };
  }
}

async function handler(
  req: NextApiRequest,
  res: NextApiResponse<ResponseType>
) {
  console.log(req.session.user); // client에서 쿠키를 통해 받은 payload 정보
    
  // payload에 있는 userId를 이용해서 user의 정보를 조회한다.
  const profile = await client.user.findUnique({
    where: { id: req.session.user?.id },
  });
  res.json({
    ok: true,
    profile,
  });
}

export default withIronSessionApiRoute(withHandler("GET", handler), {
  cookieName: "carrotsession",
  password: "thisisthesomethingpassword",
});
profile
주니어 프론트엔드 개발자 입니다.

0개의 댓글