BE/node.js

[node.js/md-site]Session ๊ธฐ๋ฐ˜ kakao login ๊ตฌํ˜„

ujjulsu 2025. 3. 19. 19:31

๐Ÿ“Login ๋ฐฉ์‹

์„œ๋ฒ„๊ฐ€ ํด๋ผ์ด์–ธํŠธ ์ธ์ฆ์„ ํ™•์ธํ•˜๋Š” ๋ฐฉ์‹์€ ์ฟ ํ‚ค ์„ธ์…˜ ํ† ํฐ์ด ๋Œ€ํ‘œ์ ์ด๋‹ค.

cookie์˜ ๊ฒฝ์šฐ์—๋Š” ๋ณด์•ˆ์— ์ทจ์•ฝํ•˜๊ณ  ์šฉ๋Ÿ‰์ด ์ œํ•œ์ ์ด๋ผ๋Š” ๋‹จ์ ์ด ์žˆ๋‹ค.

๊ทธ๋ž˜์„œ ์š”์ฆ˜์—๋Š” ๊ฑฐ์˜ ๋‹ค jwt ์•„๋‹ˆ๋ฉด session์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ ๊ฐ™๋‹ค ใ…Žใ…Ž

โ“ Session ๊ธฐ๋ฐ˜


  • ํด๋ผ์ด์–ธํŠธ์˜ ๋ฏผ๊ฐํ•œ ์ธ์ฆ ์ •๋ณด๋ฅผ ์„œ๋ฒ„ ์ธก์—์„œ ์ €์žฅ / ๊ด€๋ฆฌ
    • cookie๋Š” ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๊ด€๋ฆฌํ–ˆ๋‹ค…
    • ์„œ๋ฒ„ ๋ฉ”๋ชจ๋ฆฌ ์ €์žฅํ•ด๋„ ๋˜๊ณ  ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅํ•ด๋„ ๋œ๋‹ค!

Session ์ธ์ฆ ๋ฐฉ์‹ ์ •๋ฆฌ

  • ์œ ์ €๊ฐ€ ๋กœ๊ทธ์ธํ•˜๋ฉด ์„ธ์…˜์— ์„œ๋ฒ„์— ์ €์žฅ
    • session id๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ •๋ณด ์ €์žฅํ•จ
  • ์„œ๋ฒ„๋Š” ๋ธŒ๋ผ์šฐ์ €์˜ ์ฟ ํ‚ค์— session id ์ €์žฅ
  • request์—์„œ session id๋ฅผ ์ฟ ํ‚ค์— ๋‹ด์•„ ์ „์†ก
  • ์„œ๋ฒ„๋Š” ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋ณด๋‚ธ session id์™€ ์„œ๋ฒ„์—์„œ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” session id๋ฅผ ๋น„๊ตํ•˜์—ฌ ์ธ์ฆ ์ˆ˜ํ–‰

Session ๊ธฐ๋ฐ˜ ๋กœ๊ทธ์ธ / ํšŒ์›๊ฐ€์ž…์˜ ๋‹จ์ 

  • ์„ธ์…˜ ID๋ฅผ ํƒˆ์ทจํ•˜์—ฌ ํด๋ผ์ด์–ธํŠธ๋กœ ์œ„์žฅํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์„œ๋ฒ„์—์„œ ์„ธ์…˜์„ ์ €์žฅํ•˜๋ฏ€๋กœ ์š”์ฒญ์ด ๋งŽ์œผ๋ฉด ์„œ๋ฒ„์— ๋ถ€ํ•˜๊ฐ€ ์‹ฌํ•ด์ง

โ“ ํ† ํฐ ๊ธฐ๋ฐ˜


  • ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์„œ๋ฒ„ ์ ‘์† ์‹œ ์„œ๋ฒ„๊ฐ€ ํ•ด๋‹น ํด๋ผ์ด์–ธํŠธ์— ํ† ํฐ์„ ๋ถ€์—ฌํ•˜๊ณ , ํด๋ผ์ด์–ธํŠธ๋Š” ์„œ๋ฒ„๋กœ ์š”์ฒญ์„ ๋ณด๋‚ผ ๋•Œ ์ด ํ† ํฐ์„ ๋‹ค์‹œ ๋ณด๋‚ด๊ฒŒ ๋จ.
  • ํด๋ผ์ด์–ธํŠธ์— ์ €์žฅ์ด ๋˜์–ด ์„ธ์…˜๊ณผ ๋‹ค๋ฅด๊ฒŒ ๋ถ€ํ•˜๊ฐ€ ์ƒ๊ธฐ๋Š” ๊ฒŒ ์—†์Œ.

ํ† ํฐ ์ธ์ฆ ๋ฐฉ์‹ ์ •๋ฆฌ

  • ์‚ฌ์šฉ์ž๊ฐ€ ๋กœ๊ทธ์ธํ•˜๊ณ  ์„œ๋ฒ„๊ฐ€ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ํ† ํฐ ๋ฐœ๊ธ‰
  • ํด๋ผ์ด์–ธํŠธ๋Š” ๋ฐœ๊ธ‰๋ฐ›์€ ํ† ํฐ์„ ์ฟ ํ‚ค / ์Šคํ† ๋ฆฌ์ง€์— ์ €์žฅํ•˜๊ณ  ์„œ๋ฒ„์— ์š”์ฒญ ์‹œ ํ•ด๋‹น ํ† ํฐ์„ ํ—ค๋”์— ํฌํ•จ์‹œ์ผœ ์ „๋‹ฌ.
  • ์„œ๋ฒ„๋Š” ์ „๋‹ฌ๋ฐ›์€ ํ† ํฐ์„ ๊ฒ€์ฆํ•˜๊ณ  ์š”์ฒญ์— ์‘๋‹ต
    • DB ์กฐํšŒํ•˜์ง€ ์•Š์•„๋„ ๋จ!

ํ† ํฐ์˜ ๋‹จ์ 

  • ๋ฐ์ดํ„ฐ ๊ธธ์ด๊ฐ€ ๊ธธ์–ด ์ธ์ฆ ์š”์ฒญ์ด ๋งŽ์œผ๋ฉด ๋„คํŠธ์›Œํฌ ๋ถ€ํ•˜๊ฐ€ ์ƒ๊น€
  • payload๋Š” ์•”ํ˜ธํ™”ํ•˜์ง€ ์•Š๊ธฐ์— ์œ ์ €์˜ ์ค‘์š”ํ•œ ์ •๋ณด ๋‹ด๊ธฐ ๋ถˆ๊ฐ€
  • ํ† ํฐ ํƒˆ์ทจ ์‹œ ๋Œ€์ฒ˜ ์–ด๋ ค์›€
    • ์ด ๋•Œ๋ฌธ์— ์‚ฌ์šฉ๊ธฐ๊ฐ„ ์ œํ•œ์„ ๋‘๊ณ  refresh ํ† ํฐ์„ ๋ฐœ๊ธ‰ํ•˜๊ฒŒ ๋จ.

โ“JWT๊ฐ€ ๋Œ€ํ‘œ์ ์ธ ํ† ํฐ ์ธ์ฆ ๋ฐฉ์‹์ด๊ณ  ์—ฌ๊ธฐ์„œ ํ† ํฐ์„ Base64๋กœ ์•”ํ˜ธํ™”ํ•œ๋‹ค๋Š” ์ ์ด ํŠน์ง•์ด๋‹ค.

๐Ÿ˜… ๋‚ด๊ฐ€ Session์„ ์„ ํƒํ•œ ์ด์œ 


  • ์ผ๋‹จ ์ง€๊ธˆ ๊ฐœ๋ฐœํ•˜๋Š” ์‚ฌ์ดํŠธ๊ฐ€ ๋‹ค์ˆ˜์˜ ์‚ฌ์šฉ์ž๋“ค์ด ํ•œ ๋ฒˆ์— ๋ชฐ๋ฆฌ๋Š” ์‚ฌ์ดํŠธ๊ฐ€ ์•„๋‹ˆ๋ผ๊ณ  ํŒ๋‹จํ•˜์—ฌ ์„ธ์…˜์„ ์‚ฌ์šฉํ–ˆ๋‹ค.
    • ์„œ๋ฒ„์— ๋ถ€๋‹ด์„ ์ค„ ์ •๋„๊ฐ€ ์•„๋‹ˆ๋ผ๊ณ  ์ƒ๊ฐํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค!
  • ๋งค๋ฒˆ ํ”„๋ก ํŠธ์—”๋“œ์—์„œ JWT ํ† ํฐ์„ ํ—ค๋”์— ๋‹ด์•„์„œ ๋ณด๋‚ด์ฃผ์–ด์•ผ ํ•˜๋Š”๋ฐ ๊ทธ๊ฒŒ ์„ฑ๊ฐ€์‹ค ๊ฒƒ ๊ฐ™์•„์„œ…

๐Ÿ“ KAKAO LOGIN

๐Ÿ—ฟ ํšŒ์›๊ฐ€์ž… ๋Œ€๋žต์ ์ธ ๊ณผ์ •


  ๐Ÿ’ก

  1. ์ธ๊ฐ€์ฝ”๋“œ ์š”์ฒญ
  2. ์นด์นด์˜ค์—์„œ ์•ก์„ธ์Šคํ† ํฐ ๋ฐ›๊ธฐ
  3. ๋ฐ›์€ ์•ก์„ธ์Šคํ† ํฐ์œผ๋กœ ์‚ฌ์šฉ์ž ์ •๋ณด ์กฐํšŒ
  4. ๋ฐ›์€ ์‚ฌ์šฉ์ž ์ •๋ณด๋กœ DB์— ์ €์žฅ
  5. Session์— ๋ณด๊ด€ 

์‚ฌ์‹ค ์ด์ „์— JWT๋ฅผ ์ด์šฉํ•œ kakao ๋กœ๊ทธ์ธ์„ ๊ตฌํ˜„ํ•ด๋ดค์–ด์„œ kakao ๊ด€๋ จ๋œ ๊ฑด ๊ดœ์ฐฎ์•˜๋‹ค ใ…Žใ…Ž

๐Ÿ˜… ๋‚ฏ์„ค์—ˆ๋˜ ๋ถ€๋ถ„ ๋“ฑ์„ ์ •๋ฆฌ


โœจ node.js์—์„œ axios ์ด์šฉ

Spring์—์„œ๋Š” ์™ธ๋ถ€ api๋ฅผ ์ด์šฉํ•ด๋ดค์ง€๋งŒ ๋…ธ๋“œ์—์„œ ์™ธ๋ถ€ api๋ฅผ ์‚ฌ์šฉํ•œ ์ ์ด ์—†์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ž˜ ๋ชฐ๋ž๋Š”๋ฐ react.js์—์„œ ๋ฐฑ์—”๋“œ๋กœ๋ถ€ํ„ฐ api ์š”์ฒญํ•  ๋•Œ์ฒ˜๋Ÿผ axios๋ฅผ ์ด์šฉํ•œ๋‹ค๋Š” ์ ์„ ์•Œ๊ฒŒ ๋˜์—ˆ๋‹ค.

const tokenResponse = await axios.post(
            "<https://kauth.kakao.com/oauth/token>",
            null,
            {
                params:{
                    "grant_type" : "authorization_code",
                    "client_id" : KAKAO_REST_API_KEY,
                    "redirect_uri" : REDIRECT_URI,
                    code,
                },
                headers: {
                    "Content-Type": "application/x-www-form-urlencoded;charset=utf-8",
                  },
            }
        );

์—ญ์‹œ ๊ฐ™์€ ๊ณ„์—ด์ด๋ผ ๊ทธ๋Ÿฐ ๊ฒƒ ๊ฐ™๋‹ค…!

๐Ÿ˜Ž ํ˜•์‹ ์ฃผ์˜!!

์ด๊ฑฐ๋Š” ๋‚ฏ์„ค์—ˆ๋˜ ๊ฒƒ์€ ์•„๋‹ˆ๊ณ  ๊ทธ๋ƒฅ ๋‚ด๊ฐ€ ์‹ค์ˆ˜ํ–ˆ๋˜ ๋ถ€๋ถ„!

const email = userResponse.kakao_account.email;

์ด๋ ‡๊ฒŒ email์„ ๋ฐ›์•„์˜ค๋Š”๋ฐ ์ž๊พธ email ๊ฐ’์ด ์•ˆ ๋ฐ›์•„์ ธ์„œ ๋ณด๋‹ˆ๊นŒ ์ž˜ ๋ชปํ•˜๊ณ  ์žˆ์—ˆ์Œ!!

const email = userResponse.data.kakao_account.email;

์ด๋ ‡๊ฒŒ ํ•ด์•ผ ์ •์ƒ์ ์œผ๋กœ ๋‚˜์˜ค๋Š”๋ฐ ใ… ใ… 

๋ฏธ๋ฆฌ ์ฝ˜์†”์— ์ฐ์–ด๋ณด๊ธฐ๋งŒ ํ•ด๋„ ์•„๋Š”๋ฐ ์ด๋Ÿฐ ์‹ค์ˆ˜๋ฅผ ํ•ด์„œ ํ™ฉ๋‹นํ–ˆ๋‹ค…

โœจ Session ์‚ฌ์šฉ

req.session.user = {
                "id": user._id,
                "email": user.email
            };

๋งจ๋‚  query๋‚˜ body๋งŒ req์—์„œ ๋ฐ›์•„์™”์ง€ req์— ์ €์žฅํ•˜๋Š” ๊ฑด ์ฒ˜์Œ์ด๋ผ ๋„ˆ๋ฌด ์‹ ๊ธฐํ–ˆ๋‹ค ใ…Žใ…Ž

const userEmail = req.session.user?.email;

์—ฌ๊ธฐ์„œ ?๋ฅผ ํ•˜์ง€ ์•Š์œผ๋ฉด ํ•ด๋‹น ๊ฐ’์ด ์—†์œผ๋ฉด error๊ฐ€ ๋‚˜๋Š”๋ฐ, ?๋ฅผ ๋ถ™์ด๋ฉด null๋กœ ๋ฐ˜ํ™˜ํ•œ๋‹ค๊ณ  ํ•œ๋‹ค. ๋กœ๊ทธ์ธํ•˜์ง€ ์•Š์€ ์œ ์ € ํŒ๋ณ„ ์‹œ์— ์šฉ์ดํ•  ๊ฒƒ ๊ฐ™๋‹ค!

components: {
      securitySchemes: {
        cookieAuth: {
          type: 'apiKey',
          in: 'cookie',
          name: 'connect.sid', // ์„ธ์…˜ ์ฟ ํ‚ค ์ด๋ฆ„ (๊ธฐ๋ณธ๊ฐ’์ด connect.sid)
          description: '์„ธ์…˜ ๊ธฐ๋ฐ˜ ์ธ์ฆ'
        },
      },
    },
    security: [
      {
        cookieAuth: [],
      },
    ],

์—ญ์‹œ๋‚˜ swagger๋„ ์„ธ์…˜ ์ธ์ฆ์„ ์œ„ํ•œ ์„ค์ •์ด ํ•„์š”ํ–ˆ๋‹ค!!

๐Ÿ’ฌ ๋‚ด ์ƒ๊ฐ

๋Œ€๊ทœ๋ชจ ์„œ๋น„์Šค๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ์—๋Š” ์„ธ์…˜์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ํŽธํ•˜๊ธด ํ•œ ๊ฒƒ ๊ฐ™๋‹ค… ๊ทธ๋ ‡์ง€๋งŒ,, ๋Œ€๊ทœ๋ชจ ์„œ๋น„์Šค๋ฅผ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋Š” ๊ณณ์— ์ทจ์—…ํ•  ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ใ… ใ… 

console์— ๋กœ๊ทธ๋ฅผ ๋‚จ๊ธฐ๋Š” ์ž‘์—…์ด ์—„์ฒญ ์ค‘์š”ํ•œ ๊ฒƒ ๊ฐ™๋‹ค

๋กœ๊ทธ๋งŒ ๋‚จ๊ฒผ์–ด๋„ ๋ฐ”๋กœ ๋ฌธ์ œ์ ์ด ๋ณด์ด๋‹ˆ๊นŒ ์•ž์œผ๋กœ๋Š” ๋กœ๊ทธ๋ฅผ ๊น”๋”ํ•˜๊ฒŒ ๋‚จ๊ธฐ๋Š” ๊ฑธ ์—ฐ์Šตํ•ด์•ผ๊ฒ ๋‹ค ๐Ÿ˜๐Ÿ˜