๐Ÿ“ฆ ์„ธ์…˜

์€์œ ๋กœ๊ทธยท2021๋…„ 10์›” 25์ผ
0

๐Ÿ“š study

๋ชฉ๋ก ๋ณด๊ธฐ
13/21
post-thumbnail
post-custom-banner

์„ธ์…˜(Session)


์„ธ์…˜

  • ์ผ์ • ์‹œ๊ฐ„๋™์•ˆ ๊ฐ™์€ ํด๋ผ์ด์–ธํŠธ๋กœ๋ถ€ํ„ฐ ๋“ค์–ด์˜ค๋Š” ์š”๊ตฌ๋ฅผ ํ•˜๋‚˜์˜ ์ƒํƒœ๋กœ ๋ณด๊ณ , ๊ทธ ์ƒํƒœ๋ฅผ ์ผ์ •ํ•˜๊ฒŒ ์œ ์ง€์‹œํ‚ค๋Š” ๊ธฐ์ˆ ์ด๋‹ค.
  • HTTP๋Š” ๋ฌด์ƒํƒœ(stateless)์ด๊ธฐ ๋•Œ๋ฌธ์— ๋กœ๊ทธ์ธ ์ƒํƒœ๋ฅผ ์œ ์ง€์‹œํ‚ค๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” ๊ธฐ์ˆ  ์ค‘ ํ•˜๋‚˜์ด๋‹ค.

์„ธ์…˜์˜ ํŠน์ง•

  • ์„ธ์…˜ID๋Š” ์›น ๋ธŒ๋ผ์šฐ์ € ๋‹น 1๊ฐœ์”ฉ ์ƒ์„ฑ๋˜๋ฉฐ ๋ธŒ๋ผ์šฐ์ € ์ข…๋ฃŒ์‹œ ์†Œ๋ฉธ๋œ๋‹ค.
    ๋กœ๊ทธ์•„์›ƒํ•˜๋ฉด ์ƒˆ๋กœ์šด ์‚ฌ์šฉ์ž๋กœ ์ธ์‹ํ•ด์„œ ์ƒˆ๋กœ์šด ์„ธ์…˜์ด ์ƒ์„ฑ๋œ๋‹ค.
  • ์ฟ ํ‚ค๋ณด๋‹ค ๋น„๊ต์  ๋ณด์•ˆ์ด ์ข‹๋‹ค.
  • ์ฟ ํ‚ค์— ์„ธ์…˜ID๋ฅผ ๋‹ด์•„ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ๋ณด๋‚ด๊ณ , ๋ณด์•ˆ์„ ์œ„ํ•ด httpOnly, secure ๊ฐ™์€ ์˜ต์…˜์„ ์‚ฌ์šฉํ•œ๋‹ค.
  • ์„œ๋ฒ„ ์šฉ๋Ÿ‰์ด ํ—ˆ์šฉํ•˜๋Š” ํ•œ ์ €์žฅ ๋ฐ์ดํ„ฐ์— ์ œํ•œ์ด ์—†๋‹ค.
  • ๋ณด์•ˆ ์ธ์ฆ ์ •๋ณด๋Š” ์„œ๋ฒ„์— ์ €์žฅ๋œ๋‹ค.

์„ธ์…˜ ํ๋ฆ„

  1. ํด๋ผ์ด์–ธํŠธโžก๏ธ์„œ๋ฒ„ // ์‚ฌ์šฉ์ž๊ฐ€ ๋กœ๊ทธ์ธ์„ ํ•œ๋‹ค.
  2. ์„œ๋ฒ„โžก๏ธ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค // ์ž…๋ ฅ๋ฐ›์€ ID, ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์กด์žฌํ•˜๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.
  3. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šคโžก๏ธ์„œ๋ฒ„ // ์กด์žฌํ•œ๋‹ค๋ฉด ์„ธ์…˜ID๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
  4. ์„œ๋ฒ„โžก๏ธํด๋ผ์ด์–ธํŠธ // ์•”ํ˜ธํ™”ํ•œ ์„ธ์…˜ID๋ฅผ ์ฟ ํ‚ค์— ๋‹ด์•„ ์‘๋‹ตํ•œ๋‹ค.

5 ~ 8 ์ดํ›„ ์‚ฌ์šฉ์ž ID, ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ์•„๋‹Œ ์ฟ ํ‚ค์— ๋‹ด๊ธด ์„ธ์…˜ID๋กœ ์‚ฌ์šฉ์ž๋ฅผ ํ™•์ธํ•œ๊ณ  ๋™์ž‘ํ•œ๋‹ค.

!! HTTPS ํ๋ฆ„ ์ค‘ 7 ~ 8 ๋ถ€๋ถ„์ด๋‹ค !!

์„ธ์…˜ ๊ตฌํ˜„

์„ธ์…˜ ์„ค์ •

session({
    secret: '@codestates',
    resave: false, // ์„ธ์…˜์„ ํ•ญ์ƒ ์ €์žฅํ• ์ง€ ์„ค์ •
    saveUninitialized: true, // ์„ธ์…˜์ด ์ €์žฅ๋˜๊ธฐ ์ „ uninitialized ์ƒํƒœ๋กœ ์ €์žฅ
    cookie: {
      domain: 'localhost', // ์ฟ ํ‚ค๋ฅผ ๋ณด๋‚ผ ์ฃผ์†Œ
      path: '/', // URL ๊ฒฝ๋กœ
      maxAge: 24 * 6 * 60 * 10000, // ์ฟ ํ‚ค ์œ ํšจ์‹œ๊ฐ„
      sameSite: 'None', // ์ฟ ํ‚ค๋ฅผ ์ „์†กํ•ด์•ผ ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ํ”„๋กœํ† ์ฝœ์— ๋”ฐ๋ฅธ ์ฟ ํ‚ค ์ „์†ก ์—ฌ๋ถ€๋ฅผ ๊ฒฐ์ •
      // Strict : same-site ์ธ ๊ฒฝ์šฐ์—๋งŒ ์ฟ ํ‚ค๋ฅผ ์ „์†ก ๊ฐ€๋Šฅ
      // Lax : GET ๋ฉ”์†Œ๋“œ์ธ ๊ฒฝ์šฐ์—๋งŒ ์ฟ ํ‚ค ์ „์†ก ๊ฐ€๋Šฅ
      // None : ๋ญ๋“  ์ฟ ํ‚ค ์ „์†ก ๊ฐ€๋Šฅ -> secure: true ํ•„์ˆ˜
      httpOnly: true, // ํด๋ผ์ด์–ธํŠธ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์ฟ ํ‚ค๋ฅผ ๋ชป๋ณด๊ฒŒ ํ•จ (document.cookie) -> ๋ณด์•ˆ๊ฐ•ํ™”
      secure: true, // HTTPS์ผ ๊ฒฝ์šฐ์—๋งŒ ์ฟ ํ‚ค๋ฅผ ์ „์†ก
    },
  })

cors ์„ค์ •

cors({
    // origin: 'https://localhost:3000',
    origin: true,
    methods: ['GET', 'POST', 'OPTIONS'],
    credentials: true, // ๋‹ค๋ฅธ ๋„๋ฉ”์ธ๊ฐ„ ์ž๊ฒฉ์ฆ๋ช…(credential, ์ฟ ํ‚ค ํฌํ•จ)์„ ์ „์†กํ• ์ง€ ์—ฌ๋ถ€
  })

credential์€ ์—ฌ๊ธฐ๋ฅผ ์ฐธ๊ณ ํ•˜์ž

login

module.exports = {
  post: async (req, res) => {
    // userInfo๋Š” ์œ ์ €์ •๋ณด๊ฐ€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์กด์žฌํ•˜๊ณ , ์™„๋ฒฝํžˆ ์ผ์น˜ํ•˜๋Š” ๊ฒฝ์šฐ์—๋งŒ ๋ฐ์ดํ„ฐ๊ฐ€ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.
    // ๋งŒ์•ฝ userInfo๊ฐ€ NULL ํ˜น์€ ๋นˆ ๊ฐ์ฒด๋ผ๋ฉด ์ „๋‹ฌ๋ฐ›์€ ์œ ์ €์ •๋ณด๊ฐ€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์กด์žฌํ•˜๋Š”์ง€ ํ™•์ธํ•ด ๋ณด์„ธ์š”

    const userInfo = await Users.findOne({
      where: { userId: req.body.userId, password: req.body.password },
    });
    // console.log(userInfo);
    
    if (!userInfo) {
      // TODO: ์œ ์ € ์ •๋ณด๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ
      res.status(400).send({ message: 'not authorized' });
    } else {
      // TODO: ๊ฒฐ๊ณผ๊ฐ€ ์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ ์„ธ์…˜ ๊ฐ์ฒด์— userId๊ฐ€ ์ €์žฅ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
      // HINT: req.session์„ ์‚ฌ์šฉํ•˜์„ธ์š”.
      req.session.userId = req.body.userId;
      //console.log(req.session);
      // TODO: ์œ ์ € ์ •๋ณด๊ฐ€ ์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ
      res.status(200).json({ data: userInfo, message: 'ok' };
    }
  },
};

logout

module.exports = {
  post: (req, res) => {
    // TODO: ์„ธ์…˜ ์•„์ด๋””๋ฅผ ํ†ตํ•ด ๊ณ ์œ ํ•œ ์„ธ์…˜ ๊ฐ์ฒด์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    // ์•ž์„œ ๋กœ๊ทธ์ธ์‹œ ์„ธ์…˜ ๊ฐ์ฒด์— ์ €์žฅํ–ˆ๋˜ ๊ฐ’์ด ์กด์žฌํ•  ๊ฒฝ์šฐ, ์ด๋ฏธ ๋กœ๊ทธ์ธํ•œ ์ƒํƒœ๋กœ ํŒ๋‹จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    // ์„ธ์…˜ ๊ฐ์ฒด์— ๋‹ด๊ธด ๊ฐ’์˜ ์กด์žฌ ์—ฌ๋ถ€์— ๋”ฐ๋ผ ์‘๋‹ต์„ ๊ตฌํ˜„ํ•˜์„ธ์š”.
    // console.log(req.session);
    if (!req.session.userId) {
      res.status(400).send("not authorized");
    } else {
      // TODO: ๋กœ๊ทธ์•„์›ƒ ์š”์ฒญ์€ ์„ธ์…˜์„ ์‚ญ์ œํ•˜๋Š” ๊ณผ์ •์„ ํฌํ•จํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
      req.session.destroy(); // ! session.destroy() ๋ฉ”์†Œ๋“œ ์‚ฌ์šฉ์‹œ ์„ธ์…˜ ํŒŒ๊ดดํ•จ
      res.json("ok");
    }
  },
};
profile
เน‘โ€ขโ€ฟโ€ขเน‘
post-custom-banner

0๊ฐœ์˜ ๋Œ“๊ธ€