๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

Dev.log/Node.js

[Node.js ๊ต๊ณผ์„œ] #35. ์ต์Šคํ”„๋ ˆ์Šค๋กœ SNS ์„œ๋น„์Šค ๋งŒ๋“ค๊ธฐ - Passport ๋ชจ๋“ˆ๋กœ ๋กœ๊ทธ์ธ ๊ตฌํ˜„ํ•˜๊ธฐ

Passport ๋ชจ๋“ˆ๋กœ ๋กœ๊ทธ์ธ ๊ตฌํ˜„ํ•˜๊ธฐ

SNS ์„œ๋น„์Šค์ด๋ฏ€๋กœ ๋กœ๊ทธ์ธ์ด ํ•„์š”ํ•˜๋‹ค. ํšŒ์›๊ฐ€์ž…๊ณผ ๋กœ๊ทธ์ธ์€ ์ง์ ‘ ๊ตฌํ˜„ํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ, ์„ธ์…˜๊ณผ ์ฟ ํ‚ค ์ฒ˜๋ฆฌ ๋“ฑ ๋ณต์žกํ•œ ์ž‘์—…์ด ๋งŽ์œผ๋ฏ€๋กœ ๊ฒ€์ฆ๋œ ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค. ๋ฐ”๋กœ Passport๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์ด๋ฆ„์ฒ˜๋Ÿผ ์šฐ๋ฆฌ์˜ ์„œ๋น„์Šค๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ์—ฌ๊ถŒ ์—ญํ• ์„ ํ•œ๋‹ค.

์š”์ฆ˜์—๋Š” ์„œ๋น„์Šค์— ๋กœ๊ทธ์ธ์„ ํ•  ๋•Œ ์•„์ด๋””์™€ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด์„œ ํ•˜์ง€ ์•Š๊ณ  ๊ตฌ๊ธ€, ํŽ˜์ด์Šค๋ถ, ์นด์นด์˜คํ†ก ๊ฐ™์€ ๊ธฐ์กด์˜ SNS ์„œ๋น„์Šค ๊ณ„์ •์œผ๋กœ ๋กœ๊ทธ์ธํ•˜๊ธฐ๋„ ํ•œ๋‹ค. ์ด ๋˜ํ•œ Passport๋ฅผ ์‚ฌ์šฉํ•ด์„œ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค. 

1. Passport ๊ด€๋ จ ํŒจํ‚ค์ง€ ์„ธํŒ…ํ•˜๊ธฐ

1-1. Passport ๊ด€๋ จ ํŒจํ‚ค์ง€๋“ค์„ ์„ค์น˜ํ•œ๋‹ค.

 

npm i passport passport-local passport-kakao bcrypt

 

1-2. Passport ๋ชจ๋“ˆ์„ ๋ฏธ๋ฆฌ app.js์™€ ์—ฐ๊ฒฐํ•˜๊ธฐ

 

app.js

 

  • require('./passport') : require('./passport/index.js')์™€ ๊ฐ™๋‹ค. ํด๋” ๋‚ด์˜ index.js ํŒŒ์ผ์€ require ์‹œ ์ด๋ฆ„์„ ์ƒ๋žตํ•  ์ˆ˜ ์žˆ๋‹ค.

 

app.js

 

  • passport.initialize() : ์š”์ฒญ(req ๊ฐ์ฒด)์— passport ์„ค์ •์„ ์‹ฌ๋Š”๋‹ค.
  • passport.session() : req.session ๊ฐ์ฒด์— passport ์ •๋ณด๋ฅผ ์ €์žฅํ•œ๋‹ค.
    • req.session ๊ฐ์ฒด๋Š” express-session์—์„œ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์ด๋ฏ€๋กœ passport ๋ฏธ๋“ค์›จ์–ด๋Š” express-session ๋ฏธ๋“ค์›จ์–ด๋ณด๋‹ค ๋’ค์— ์—ฐ๊ฒฐํ•ด์•ผ ํ•œ๋‹ค.

 

1-3. Passport ๋ชจ๋“ˆ ์ž‘์„ฑํ•˜๊ธฐ

 

passport\index.js

 

  • localStrategy์™€ kakaoStrategy : ๋กœ์ปฌ ๋กœ๊ทธ์ธ๊ณผ ์นด์นด์˜ค ๋กœ๊ทธ์ธ ์ „๋žต์— ๋Œ€ํ•œ ํŒŒ์ผ์ด๋‹ค. Passport๋Š” ๋กœ๊ทธ์ธ ์‹œ์˜ ๋™์ž‘์„ ์ „๋žต(strategy)์ด๋ผ๋Š” ์šฉ์–ด๋กœ ํ‘œํ˜„ํ•˜๊ณ  ์žˆ๋‹ค.
  • passport.serializeUser() : req.session ๊ฐ์ฒด์— ์–ด๋–ค ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ• ์ง€ ์„ ํƒํ•œ๋‹ค. ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ user๋ฅผ ๋ฐ›์•„ done ํ•จ์ˆ˜์— ๋‘ ๋ฒˆ์งธ ์ธ์ž๋กœ user.id๋ฅผ ๋„˜๊ธฐ๊ณ  ์žˆ๋‹ค. done ํ•จ์ˆ˜์˜ ์ฒซ ๋ฒˆ์งธ ์ธ์ž๋Š” ์—๋Ÿฌ ๋ฐœ์ƒ ์‹œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๋ฏ€๋กœ ๋‘ ๋ฒˆ์งธ ์ธ์ž๊ฐ€ ์ค‘์š”ํ•˜๋‹ค. 
    • ์„ธ์…˜์— ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ๋ชจ๋‘ ์ €์žฅํ•˜๋ฉด ์„ธ์…˜์˜ ์šฉ๋Ÿ‰์ด ์ปค์ง€๊ณ  ๋ฐ์ดํ„ฐ ์ผ๊ด€์„ฑ์— ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฏ€๋กœ ์‚ฌ์šฉ์ž์˜ ์•„์ด๋””๋งŒ ์ €์žฅํ•˜๋ผ๊ณ  ๋ช…๋ นํ•œ ๊ฒƒ์ด๋‹ค.
  • passport.deserializeUser() : ๋งค ์š”์ฒญ ์‹œ ์‹คํ–‰๋œ๋‹ค. passport.session() ๋ฏธ๋“ค์›จ์–ด๊ฐ€ ์ด ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค. ์ข€ ์ „์— serializeUser์—์„œ ์„ธ์…˜์— ์ €์žฅํ–ˆ๋˜ ์•„์ด๋””๋ฅผ ๋ฐ›์•„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ์กฐํšŒํ•œ๋‹ค. ์กฐํšŒํ•œ ์ •๋ณด๋ฅผ req.user์— ์ €์žฅํ•˜๋ฏ€๋กœ ์•ž์œผ๋กœ req.user๋ฅผ ํ†ตํ•ด ๋กœ๊ทธ์ธํ•œ ์‚ฌ์šฉ์ž์˜ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค.

 

 

์ฆ‰, serializeUser๋Š” ์‚ฌ์šฉ์ž์˜ ์ •๋ณด ๊ฐ์ฒด๋ฅผ ์„ธ์…˜ ์•„์ด๋””๋กœ ์ €์žฅํ•˜๋Š” ๊ฒƒ์ด๊ณ , deserializeUser๋Š” ์„ธ์…˜์— ์ €์žฅํ•œ ์•„์ด๋””๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉ์ž ์ •๋ณด ๊ฐ์ฒด๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๊ฒƒ์ด๋‹ค. ์„ธ์…˜์— ๋ถˆํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด์•„๋‘์ง€ ์•Š๊ธฐ ์œ„ํ•œ ๊ณผ์ •์ด๋‹ค.

 

์ „์ฒด ๊ณผ์ •์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  1. ๋กœ๊ทธ์ธ ์š”์ฒญ์ด ๋“ค์–ด์˜ด
  2. passport.authenticate ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ
  3. ๋กœ๊ทธ์ธ ์ „๋žต ์ˆ˜ํ–‰
  4. ๋กœ๊ทธ์ธ ์„ฑ๊ณต ์‹œ ์‚ฌ์šฉ์ž ์ •๋ณด ๊ฐ์ฒด์™€ ํ•จ๊ป˜ req.login ํ˜ธ์ถœ
  5. req.login ๋ฉ”์„œ๋“œ๊ฐ€ passport.serializeUser ํ˜ธ์ถœ
  6. req.session์— ์‚ฌ์šฉ์ž ์•„์ด๋””๋งŒ ์ €์žฅ
  7. ๋กœ๊ทธ์ธ ์™„๋ฃŒ

 

๋‹ค์Œ์€ ๋กœ๊ทธ์ธ ์ดํ›„์˜ ๊ณผ์ •์ด๋‹ค.

  1. ๋ชจ๋“  ์š”์ฒญ์— passport.session() ๋ฏธ๋“ค์›จ์–ด๊ฐ€ passport.deserializeUser ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ
  2. req.session์— ์ €์žฅ๋œ ์•„์ด๋””๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์‚ฌ์šฉ์ž ์กฐํšŒ
  3. ์กฐํšŒ๋œ ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ req.user์— ์ €์žฅ
  4. ๋ผ์šฐํ„ฐ์—์„œ req.user ๊ฐ์ฒด ์‚ฌ์šฉ ๊ฐ€๋Šฅ

2. ๋กœ์ปฌ ๋กœ๊ทธ์ธ ๊ตฌํ˜„ํ•˜๊ธฐ

๋กœ์ปฌ ๋กœ๊ทธ์ธ์ด๋ž€ ๋‹ค๋ฅธ SNS ์„œ๋น„์Šค๋ฅผ ํ†ตํ•ด ๋กœ๊ทธ์ธํ•˜์ง€ ์•Š๊ณ , ์ž์ฒด์ ์œผ๋กœ ํšŒ์›๊ฐ€์ž… ํ›„ ๋กœ๊ทธ์ธํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค. ์ฆ‰, ์•„์ด๋””/๋น„๋ฐ€๋ฒˆํ˜ธ ๋˜๋Š” ์ด๋ฉ”์ผ/๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ํ†ตํ•ด ๋กœ๊ทธ์ธํ•˜๋Š” ๊ฒƒ์ด๋‹ค. Passport์—์„œ ์ด๋ฅผ ๊ตฌํ˜„ํ•˜๋ ค๋ฉด passport-local ๋ชจ๋“ˆ์ด ํ•„์š”ํ•˜๋‹ค. ์ด๋ฏธ ์„ค์น˜ํ–ˆ์œผ๋ฏ€๋กœ ๋กœ์ปฌ ๋กœ๊ทธ์ธ ์ „๋žต๋งŒ ์„ธ์šฐ๋ฉด ๋œ๋‹ค. ๋กœ๊ทธ์ธ์—๋งŒ ํ•ด๋‹นํ•˜๋Š” ์ „๋žต์ด๋ฏ€๋กœ ํšŒ์›๊ฐ€์ž…์€ ๋”ฐ๋กœ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค.

ํšŒ์›๊ฐ€์ž…, ๋กœ๊ทธ์ธ, ๋กœ๊ทธ์•„์›ƒ ๋ผ์šฐํ„ฐ๋ฅผ ๋จผ์ € ๋งŒ๋“ค์–ด๋ณด์ž. ์ด๋Ÿฌํ•œ ๋ผ์šฐํ„ฐ๋Š” ์ ‘๊ทผ ์กฐ๊ฑด์ด ์žˆ๋‹ค. ๋กœ๊ทธ์ธํ•œ ์‚ฌ์šฉ์ž๋Š” ํšŒ์›๊ฐ€์ž…๊ณผ ๋กœ๊ทธ์ธ ๋ผ์šฐํ„ฐ์— ์ ‘๊ทผํ•˜๋ฉด ์•ˆ ๋œ๋‹ค. (์ด๋ฏธ ๋กœ๊ทธ์ธ์„ ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์—) ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋กœ๊ทธ์ธํ•˜์ง€ ์•ˆํ” ์‚ฌ์šฉ์ž๋Š” ๋กœ๊ทธ์•„์›ƒ ๋ผ์šฐํ„ฐ์— ์ ‘๊ทผํ•˜๋ฉด ์•ˆ ๋œ๋‹ค. ๋”ฐ๋ผ์„œ ๋ผ์šฐํ„ฐ์— ์ ‘๊ทผ ๊ถŒํ•œ์„ ์ œ์–ดํ•˜๋Š” ๋ฏธ๋“ค์›จ์–ด๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

 

 

Passport๋Š” req ๊ฐ์ฒด์— isAuthenticated ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค. ๋กœ๊ทธ์ธ ์ค‘์ด๋ฉด re.isAuthenticated()๊ฐ€ true์ด๊ณ , ์•„๋‹ˆ๋ฉด false์ด๋‹ค. ๋”ฐ๋ผ์„œ ๋กœ๊ทธ์ธ ์—ฌ๋ถ€๋ฅผ ์ด ๋ฉ”์„œ๋“œ๋กœ ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ผ์šฐํ„ฐ ์ค‘์— ๋กœ๊ทธ์•„์›ƒ ๋ผ์šฐํ„ฐ๋‚˜ ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ ๋ผ์šฐํ„ฐ ๋“ฑ์€ ๋กœ๊ทธ์ธํ•œ ์‚ฌ๋žŒ๋งŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์•ผ ํ•˜๊ณ , ํšŒ์›๊ฐ€์ž… ๋ผ์šฐํ„ฐ๋‚˜ ๋กœ๊ทธ์ธ ๋ผ์šฐํ„ฐ๋Š” ๋กœ๊ทธ์ธํ•˜์ง€ ์•Š์€ ์‚ฌ๋žŒ๋งŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์•ผ ํ•œ๋‹ค. ์ด๋Ÿด ๋•Œ ๋ผ์šฐํ„ฐ์— ๋กœ๊ทธ์ธ ์—ฌ๋ถ€๋ฅผ ๊ฒ€์‚ฌํ•˜๋Š” ๋ฏธ๋“ค์›จ์–ด๋ฅผ ๋„ฃ์–ด ๊ฑธ๋Ÿฌ๋‚ผ ์ˆ˜ ์žˆ๋‹ค.

isLoggedIn๊ณผ isNotLoggedIn ๋ฏธ๋“ค์›จ์–ด๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค. ์ด ๋ฏธ๋“ค์›จ์–ด๊ฐ€ page ๋ผ์šฐํ„ฐ์— ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉ๋˜๋Š”์ง€ ๋ณด์ž.

 

routes\page.js

 

router.get('/profile', isLoggedIn ··· : ์ž์‹ ์˜ ํ”„๋กœํ•„์€ ๋กœ๊ทธ์ธ์„ ํ•ด์•ผ ๋ณผ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ isLoggedIn ๋ฏธ๋“ค์›จ์–ด๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. req.isAuthenticated()๊ฐ€ true์—ฌ์•ผ next()๊ฐ€ ํ˜ธ์ถœ๋˜์–ด res.render๊ฐ€ ์žˆ๋Š” ๋ฏธ๋“ค์›จ์–ด๋กœ ๋„˜์–ด๊ฐˆ ์ˆ˜ ์žˆ๋‹ค. false๋ผ๋ฉด ๋กœ๊ทธ์ธ ์ฐฝ์ด ์žˆ๋Š” ๋ฉ”์ธ ํŽ˜์ด์ง€๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ ๋œ๋‹ค.

router.get('/join', isNotLoggedIn ··· :  ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€๋Š” ๋กœ๊ทธ์ธ์„ ํ•˜์ง€ ์•Š์€ ์‚ฌ๋žŒ์—๊ฒŒ๋งŒ ๋ณด์—ฌ์•ผ ํ•œ๋‹ค. ๋”ฐ๋ผ์„œ isNotLoggedIn ๋ฏธ๋“ค์›จ์–ด๋กœ req.isAuthenticated()๊ฐ€ false์ผ ๋•œ๋‚ญ next()๋ฅผ ํ˜ธ์ถœํ•˜๋„๋ก ํ•˜์˜€๋‹ค. 

 

๋กœ๊ทธ์ธ ์—ฌ๋ถ€๋กœ๋งŒ ๋ฏธ๋“ค์›จ์–ด๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ํŒ”๋กœ์ž‰ ์—ฌ๋ถ€, ๊ด€๋ฆฌ์ž ์—ฌ๋ถ€ ๋“ฑ์˜ ๋ฏธ๋“ค์›จ์–ด๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๋‹ค์–‘ํ•˜๊ฒŒ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. res.render ๋ฉ”์„œ๋“œ์—์„œ user ์†์„ฑ์— req.user๋ฅผ ๋„ฃ์€ ๊ฒƒ์„ ์ฃผ๋ชฉํ•˜์ž. pug์—์„œ user ๊ฐ์ฒด๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉ์ž ์ •๋ณด์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๋‹ค.

 

์ด์ œ ํšŒ์›๊ฐ€์ž…, ๋กœ๊ทธ์ธ, ๋กœ๊ทธ์•„์›ƒ ๋ผ์šฐํ„ฐ๋ฅผ ์ž‘์„ฑํ•ด๋ณด์ž.

 

routes\auth.js

 

  • ๋‚˜์ค‘์— app.js์™€ ์—ฐ๊ฒฐํ•  ๋–„ /auth ์ ‘๋‘์‚ฌ๋ฅผ ๋ถ™์ผ ๊ฒƒ์ด๋ฏ€๋กœ ๋ผ์šฐํ„ฐ์˜ ์ฃผ์†Œ๋Š” ๊ฐ๊ฐ /auth/join, /auth/login, /auth/logout์ด ๋œ๋‹ค.
  • router.post('./join', isNotLoggedIn, ··· : ํšŒ์›๊ฐ€์ž… ๋ผ์šฐํ„ฐ์ด๋‹ค. ๊ธฐ์กด์— ๊ฐ™์€ ์ด๋ฉ”์ผ๋กœ ๊ฐ€์ž…ํ•œ ์‚ฌ์šฉ์ž๊ฐ€ ์žˆ๋Š”์ง€ ์กฐํšŒํ•œ ๋’ค, ์žˆ๋‹ค๋ฉด flash ๋ฉ”์‹œ์ง€๋ฅผ ์„ค์ •ํ•˜๊ณ  ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€๋กœ ๋˜๋Œ๋ ค๋ณด๋‚ธ๋‹ค. ์—†๋‹ค๋ฉด ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์•”ํ˜ธํ™”ํ•˜๊ณ  ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ์ƒ์„ฑํ•œ๋‹ค. ํšŒ์›๊ฐ€์ž… ์‹œ ๋น„๋ฐ€๋ฒˆํ˜ธ๋Š” ์•”ํ˜ธํ™”ํ•ด์„œ ์ €์žฅํ•ด์•ผ ํ•œ๋‹ค. ์ด๋ฒˆ์—๋Š” bcrypt ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ–ˆ๋‹ค. 
  • router.post('/login', isLoggedIn, ··· : ๋กœ๊ทธ์ธ ๋ผ์šฐํ„ฐ์ด๋‹ค. passport.authenticate('local') ๋ฏธ๋“ค์›จ์–ด๊ฐ€ ๋กœ์ปฌ ๋กœ๊ทธ์ธ ์ „๋žต์„ ์ˆ˜ํ–‰ํ•œ๋‹ค. ๋ฏธ๋“ค์›จ์–ด์ธ๋ฐ ๋ผ์šฐํ„ฐ ๋ฏธ๋“ค์›จ์–ด ์•ˆ์— ๋“ค์–ด ์žˆ๋‹ค. ๋ฏธ๋“ค์›จ์–ด์— ์‚ฌ์šฉ์ž ์ •์˜ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ์„ ๋•Œ ๋ณดํ†ต ์ด๋ ‡๊ฒŒ ํ•œ๋‹ค. ์ด๋Ÿด ๋•Œ๋Š” ๋‚ด๋ถ€ ๋ฏธ๋“ค์›จ์–ด์— (req, res, next)๋ฅผ ์ธ์ž๋กœ ์ œ๊ณตํ•ด์„œ ํ˜ธ์ถœํ•˜๋ฉด ๋œ๋‹ค.
  • router.get('/logout', isLoggedIn, ··· : ๋กœ๊ทธ์•„์›ƒ ๋ผ์šฐํ„ฐ์ด๋‹ค. req.logout ๋ฉ”์„œ๋“œ๋Š” req.user ๊ฐ์ฒด๋ฅผ ์ œ๊ฑฐํ•˜๊ณ , req.session.destroy๋Š” req.session ๊ฐ์ฒด์˜ ๋‚ด์šฉ์„ ์ œ๊ฑฐํ•œ๋‹ค. ์„ธ์…˜ ์ •๋ณด๋ฅผ ์ง€์šด ํ›„ ๋ฉ”์ธ ํŽ˜์ด์ง€๋กœ ๋˜๋Œ์•„ ๊ฐ„๋‹ค.

 

passport\loginStrategy.js

 

  • new LocalStrategy() ์ฒซ ๋ฒˆ์งธ ์ธ์ž : ์ „๋žต์— ๊ด€ํ•œ ์„ค์ •์„ ํ•˜๋Š” ๊ณณ์ด๋‹ค. usernameField์™€ passwordField์— ์ผ์น˜ํ•˜๋Š” req.body์˜ ์†์„ฑ๋ช…์„ ์ ์–ด์ฃผ๋ฉด ๋œ๋‹ค. req.body.email์— ์ด๋ฉ”์ผ์ด, req.body.password์— ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ๋‹ด๊ฒจ ๋“ค์–ด์˜ค๋ฏ€๋กœ email๊ณผ password๋ฅผ ๊ฐ๊ฐ ๋„ฃ์–ด์ฃผ์—ˆ๋‹ค.
  • new LocalStrategy() ๋‘ ๋ฒˆ์งธ ์ธ์ž : ์‹ค์ œ ์ „๋žต์„ ์ˆ˜ํ–‰ํ•˜๋Š” async ํ•จ์ˆ˜์ด๋‹ค. ์œ„์—์„œ ๋„ฃ์–ด์ค€ email๊ณผใ… password๋Š” async ํ•จ์ˆ˜์˜ ์ฒซ ๋ฒˆ์งธ์™€ ๋‘ ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ๋œ๋‹ค. ์„ธ ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜์ธ done ํ•จ์ˆ˜๋Š” passport.authenticate์˜ ์ฝœ๋ฐฑ ํ•จ์ˆ˜์ด๋‹ค.

 

๋จผ์ € ์‚ฌ์šฉ์ž ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์ผ์น˜ํ•˜๋Š” ์ด๋ฉ”์ผ์ด ์žˆ๋Š”์ง€ ์ฐพ์€ ํ›„, ์žˆ๋‹ค๋ฉด bcrypt์˜ compare ํ•จ์ˆ˜๋กœ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ๋น„๊ตํ•œ๋‹ค. ๋น„๋ฐ€๋ฒˆํ˜ธ๊นŒ์ง€ ์ผ์น˜ํ–ˆ๋‹ค๋ฉด done ํ•จ์ˆ˜์˜ ๋‘ ๋ฒˆ์งธ ์ธ์ž๋กœ ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ๋„ฃ์–ด ๋ณด๋‚ธ๋‹ค. ๋‘ ๋ฒˆ์งธ ์ธ์ž๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ๋Š” ๋กœ๊ทธ์ธ์— ์‹คํŒจํ–ˆ์„ ๋•Œ๋ฟ์ด๋‹ค. done ํ•จ์ˆ˜์˜ ์ฒซ ๋ฒˆ์งธ ์ธ์ž๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ์„œ๋ฒ„์ชฝ์—์„œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜์˜€์„ ๋•Œ๊ณ , ์„ธ ๋ฒˆ์งธ ์ธ์ž๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ๋กœ๊ทธ์ธ ์ฒ˜๋ฆฌ ๊ณผ์ •์—์„œ ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ์ผ์น˜ํ•˜์ง€ ์•Š๊ฑฐ๋‚˜ ์กด์žฌํ•˜์ง€ ์•Š๋Š” ํšŒ์›์ผ ๋•Œ์™€ ๊ฐ™์€ ์‚ฌ์šฉ์ž ์ •์˜ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜์˜€์„ ๋•Œ์ด๋‹ค.

 

 

done์ด ํ˜ธ์ถœ๋œ ํ›„์—๋Š” ๋‹ค์‹œ passport.authenticate์˜ ์ฝœ๋ฐฑ ํ•จ์ˆ˜์—์„œ ๋‚˜๋จธ์ง€ ๋กœ์ง์ด ์‹คํ–‰๋œ๋‹ค. ๋กœ๊ทธ์ธ์— ์„ฑ๊ณตํ•˜์˜€๋‹ค๋ฉด ๋ฉ”์ธ ํŽ˜์ด์ง€๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ ๋˜๋ฉด์„œ ๋กœ๊ทธ์ธ ํผ ๋Œ€์‹  ํšŒ์› ์ •๋ณด๊ฐ€ ๋œฐ ๊ฒƒ์ด๋‹ค. ์•„์ง auth ๋ผ์šฐํ„ฐ๋ฅผ ์—ฐ๊ฒฐํ•˜์ง€ ์•Š์•˜์œผ๋ฏ€๋กœ ์ฝ”๋“œ๊ฐ€ ๋™์ž‘ํ•˜์ง€ ์•Š๋Š”๋‹ค. ์นด์นด์˜ค ๋กœ๊ทธ์ธ๊นŒ์ง€ ๊ตฌํ˜„ํ•œ ํ›„ ์—ฐ๊ฒฐํ•ด๋ณด์ž.

3. ์นด์นด์˜ค ๋กœ๊ทธ์ธ ๊ตฌํ˜„ํ•˜๊ธฐ

์นด์นด์˜ค ๋กœ๊ทธ์ธ์ด๋ž€ ๋กœ๊ทธ์ธ ์ธ์ฆ ๊ณผ์ •์„ ์นด์นด์˜ค์—๊ฒŒ ๋งก๊ธฐ๋Š” ๊ฒƒ์„ ๋œปํ•œ๋‹ค. ์‚ฌ์šฉ์ž๋“ค์€ ๋ฒˆ๊ฑฐ๋กญ๊ฒŒ ์ƒˆ๋กœ์šด ์‚ฌ์ดํŠธ์— ํšŒ์›๊ฐ€์ž…ํ•˜์ง€ ์•Š์•„๋„ ๋˜์„œ ์ข‹๊ณ , ์„œ๋น„์Šค ์ œ๊ณต์ž๋“ค์€ ๋กœ๊ทธ์ธ ๊ณผ์ •์„ ์•ˆ์‹ฌํ•˜๊ณ  ๊ฒ€์ฆ๋œ SNS์— ๋งก๊ธธ ์ˆ˜ ์žˆ์–ด์„œ ์ข‹๋‹ค.

์ด๋Ÿฌํ•œ SNS ๋กœ๊ทธ์ธ์˜ ํŠน์ง•์€ ํšŒ์›๊ฐ€์ž… ์ ˆ์ฐจ๊ฐ€ ๋”ฐ๋กœ ์—†๋‹ค. ์ฒ˜์Œ ๋กœ๊ทธ์ธํ•  ๋•Œ๋Š” ํšŒ์›๊ฐ€์ž… ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์ฃผ์–ด์•ผ ํ•˜๊ณ , ๋‘ ๋ฒˆ์งธ ๋กœ๊ทธ์ธ๋ถ€ํ„ฐ๋Š” ๋กœ๊ทธ์ธ ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค. ๋”ฐ๋ผ์„œ SNS ๋กœ๊ทธ์ธ ์ „๋žต์€ ๋กœ์ปฌ ๋กœ๊ทธ์ธ ์ „๋žต๋ณด๋‹ค ๋‹ค์†Œ ๋ณต์žกํ•˜๋‹ค.

 

passport\kakaoStrategy.js

 

  • ๋กœ์ปฌ ๋กœ๊ทธ์ธ๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์นด์นด์˜ค ๋กœ๊ทธ์ธ์— ๋Œ€ํ•œ ์„ค์ •์„ ํ•œ๋‹ค. clientID๋Š” ์นด์นด์˜ค์—์„œ ๋ฐœ๊ธ‰ํ•ด์ฃผ๋Š” ์•„์ด๋””์ด๋‹ค. ๋…ธ์ถœ๋˜์ง€ ์•Š์•„์•ผ ํ•˜๋ฏ€๋กœ process.env.KAKAO_ID๋กœ ์„ค์ •ํ•˜์˜€๋‹ค. ๋‚˜์ค‘์— ์•„์ด๋””๋ฅผ ๋ฐœ๊ธ‰๋ฐ›์•„ .env ํŒŒ์ผ์— ๋„ฃ์„ ๊ฒƒ์ด๋‹ค. callbackURL์€ ์นด์นด์˜ค๋กœ๋ถ€ํ„ฐ ์ธ์ฆ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ›์„ ๋ผ์šฐํ„ฐ ์ฃผ์†Œ์ด๋‹ค. 
  • ๋จผ์ € ๊ธฐ์กด์— ์นด์นด์˜ค๋กœ ๋กœ๊ทธ์ธํ•œ ์‚ฌ์šฉ์ž๊ฐ€ ์žˆ๋Š”์ง€ ์กฐํšŒํ•œ๋‹ค. ์žˆ๋‹ค๋ฉด done ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.
  • ์—†๋‹ค๋ฉด ํšŒ์›๊ฐ€์ž…์„ ์ง„ํ–‰ํ•œ๋‹ค. ์นด์นด์˜ค์—์„œ๋Š” ์ธ์ฆ ํ›„ callbackURL์— ์ ํžŒ ์ฃผ์†Œ๋กœ accessToken, refreshToken๊ณผ profile์„ ๋ณด๋‚ด์ค€๋‹ค. profile์— ์‚ฌ์šฉ์ž ์ •๋ณด๋“ค์ด ๋“ค์–ด ์žˆ๋‹ค. ์นด์นด์˜ค์—์„œ ๋ณด๋‚ด์ฃผ๋Š” ๊ฒƒ์ด๋ฏ€๋กœ ๋ฐ์ดํ„ฐ๋Š” console.log ๋ฉ”์„œ๋“œ๋กœ ํ™•์ธํ•˜๋ณด๋Š” ๊ฒƒ์ด ์ข‹๋‹ค. profile ๊ฐ์ฒด์—์„œ ์›ํ•˜๋Š” ์ •๋ณด๋ฅผ ๊บผ๋‚ด์™€ ํšŒ์›๊ฐ€์ž…์„ ํ•˜๋ฉด ๋œ๋‹ค. ์‚ฌ์šฉ์ž๋ฅผ ์ƒ์„ฑํ•œ ๋’ค done ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.

 

์ด์ œ ์นด์นด๋กœ ๋กœ๊ทธ์ธ ๋ผ์šฐํ„ฐ๋ฅผ ๋งŒ๋“ค์–ด๋ณด์ž. ๋กœ๊ทธ์•„์›ƒ ๋ผ์šฐํ„ฐ ์•„๋ž˜์— ์ถ”๊ฐ€ํ•˜๋ฉด ๋œ๋‹ค. ํšŒ์›๊ฐ€์ž…์„ ๋”ฐ๋กœ ์งค ํ•„์š”๊ฐ€ ์—†๊ณ , ์นด์นด์˜ค ๋กœ๊ทธ์ธ ์ „๋žต์ด ๋Œ€๋ถ€๋ถ„์˜ ๋กœ์ง์„ ์ฒ˜๋ฆฌํ•˜๋ฏ€๋กœ ๋ผ์šฐํ„ฐ๊ฐ€ ์ƒ๋Œ€์ ์œผ๋กœ ๊ฐ„๋‹จํ•˜๋‹ค.

 

routes\auth.js

 

GET /auth/kakao๋กœ ์ ‘๊ทผํ•˜๋ฉด ์นด์นด์˜ค ๋กœ๊ทธ์ธ ๊ณผ์ •์ด ์‹œ์ž‘๋œ๋‹ค. layout.pug์˜ ์นด์นด์˜คํ†ก ๋ฒ„ํŠผ์— /auth/kakao ๋งํฌ๊ฐ€ ๋ถ™์–ด ์žˆ๋‹ค.

 

views\layout.pug

 

GET /auth/kakao์—์„œ ์นด์นด์˜ค ๋กœ๊ทธ์ธ ์ฐฝ์œผ๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ๋ฅผ ํ•˜๊ณ , ๊ฒฐ๊ณผ๋ฅผ GET /auth/kakao/callback์œผ๋กœ ๋ฐ›๋Š”๋‹ค. ์ด ๋ผ์šฐํ„ฐ์—์„œ๋Š” ์บŒ์˜ค ๋กœ๊ทธ์ธ ์ „๋žต์„ ์ˆ˜ํ–‰ํ•œ๋‹ค. ๋กœ์ปฌ ๋กœ๊ทธ์ธ๊ณผ ๋‹ค๋ฅธ ์ ์€ passport.authenticate ๋ฉ”์„œ๋“œ์— ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ์ œ๊ณตํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์ ์ด๋‹ค. ์ฝœ๋ฐฑ ํ•จ์ˆ˜ ๋Œ€์‹ ์— ๋กœ๊ทธ์ธ์— ์‹คํŒจํ–ˆ์„ ๋•Œ ์–ด๋””๋กœ ์ด๋™ํ• ์ง€๋ฅผ ๊ฐ์ฒด ์•ˆ failurlRedirect ์†์„ฑ์— ์ ์–ด์ฃผ๊ณ , ์„ฑ๊ณต ์‹œ์—๋„ ์–ด๋””๋กœ ์ด๋™ํ• ์ง€๋ฅผ ๋‹ค์Œ ๋ฏธ๋“ค์›จ์–ด์— ์ ์–ด์ค€๋‹ค.

 

์ถ”๊ฐ€ํ•œ auth ๋ผ์šฐํ„ฐ๋ฅผ app.js์— ์—ฐ๊ฒฐํ•œ๋‹ค.

 

app.js

 

app.js

 

์ด์ œ kakaoStrategy.js์˜ clientID ๋ถ€๋ถ„์„ ๋ฐœ๊ธ‰๋ฐ›์•„์•ผ ํ•œ๋‹ค. ์นด์นด์˜ค ๋กœ๊ทธ์ธ์„ ์œ„ํ•ด์„œ๋Š” ์นด์นด์˜ค ๊ฐœ๋ฐœ์ž ๊ณ„์ •๊ณผ ์นด์นด์˜ค์šฉ ์•ฑ์ด ํ•„์š”ํ•˜๋‹ค. https://developers.kakao.com์— ์ ‘์†ํ•˜์—ฌ ํšŒ์›๊ฐ€์ž…์„ ํ•œ๋‹ค. ๋กœ๊ทธ์ธ ํ›„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์นด์นด์˜ค์šฉ NodeBird ์•ฑ์„ ๋งŒ๋“ ๋‹ค.

 

 

 

 

 

REST API ํ‚ค๋ฅผ ๋ณต์‚ฌํ•˜์—ฌ .env ํŒŒ์ผ์— ๋ถ™์—ฌ๋„ฃ์–ด์ค€๋‹ค. 

 

 

ํ”Œ๋žซํผ ์ถ”๊ฐ€๋ฅผ ์„ ํƒํ•œ ๋’ค ์›น ํ”Œ๋žซํผ์„ ์ถ”๊ฐ€ํ•œ๋‹ค. ์‚ฌ์ดํŠธ ๋„๋ฉ”์ธ์—๋Š” localhost:8001์„ ์ž…๋ ฅํ•œ๋‹ค. ๋งŒ์•ฝ 8001 ์™ธ์˜ ๋‹ค๋ฅธ ํฌํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค๋ฉด ํ•ด๋‹น ํฌํŠธ๋ฅผ ์ ์–ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

 

 

 

 

๋งˆ์ง€๋ง‰์œผ๋กœ Redirect Path์— /auth/kakao/callback์„ ์ž…๋ ฅํ•˜๊ณ  ์ €์žฅํ•œ๋‹ค. ์ด ๋ถ€๋ถ„์€ kakaoStrategy.js์˜ callbackURL๊ณผ ์ผ์น˜ํ•ด์•ผ ํ•œ๋‹ค.

 

 

 

 

ํ”„๋กœํ•„ ์ •๋ณด์™€ ์ด๋ฉ”์ผ์„ ์ˆ˜์ง‘ํ•˜๋„๋ก ํ•˜๊ณ  ์ˆ˜์ง‘ ๋ชฉ์ ์„ ์ž…๋ ฅํ•œ๋‹ค .์ž…๋ ฅ ํ›„์—๋Š” ์ €์žฅ ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ ์ €์žฅํ•œ๋‹ค.

 

 

์‹คํ–‰ํ•ด์„œ ๋กœ๊ทธ์ธ ํ™•์ธํ•ด๋ณด๊ธฐ

 

 

 

...

 

 

 

 

 

User.find → User.findOne์œผ๋กœ ๋ณ€๊ฒฝ ์‹œ ์‹คํ–‰๋˜๋Š” ๊ฒƒ ํ™•์ธ