Node.js - 20 Passport.js, ์ฌ์ฉ์ ์ธ์ฆ, ๋ก๊ทธ์ธ ๊ธฐ๋ฅ
Passport.js ๋ฅผ ์ฌ์ฉํ ์ฌ์ฉ์ ์ธ์ฆ
Passport.js๋ ์ฌ์ฉ์ ์ด๋ฆ/ํจ์ค์๋๋ก ํ๋ ๊ธฐ๋ณธ ๋ก๊ทธ์ธ๋ถํฐ, ํ์ด์ค๋ถ๊ณผ ๊ฐ์ ์ ์ผ์ ๋ก๊ทธ์ธ ์๋น์ค๋ฅผ ํ์ฉํ๋ ๊ฒ ๊น์ง ๊ฐ๋ฅํ๋ค.
์ด๋ฐ ๋ค์ํ ๋ก๊ทธ์ธ ๋ฉ์๋๋ค์ Strategy๋ผ๊ณ ๋ถ๋ฅด๋ฉฐ, ํด๋น ์น ์ดํ๋ฆฌ์ผ์ด์ ์์ ์ฌ์ฉํ๋ ๋ก๊ทธ์ธ ๋ฐฉ์์ ์ธ๋ถ ์๋น์ค๋ฅผ ์ด์ฉํ์ง ์๊ธฐ ๋๋ฌธ์ ๋ก์ปฌ ์คํธ๋ํฐ์ง์ด๋ค.
๋จผ์
npm -i passport passport-local-mongoose -S
๋ก passport ํจํค์ง๋ฅผ ์ค์นํ๋ค.
๊ทธ๋ฆฌ๊ณ main.js ์ ์๋์ ๊ฐ์ด ์ถ๊ฐํ๋ค.
const passport = require("passport"); //passport ๋ชจ๋ ์์ฒญ
app.use(passport.initialize()); // passport ์ด๊ธฐํ
app.use(passport.session()); // passport๊ฐ Express.js๋ด ์ธ์
์ ์ฌ์ฉํ๋๋ก ์ค์
๊ทธ๋ฆฌ๊ณ main.js์์ passport ์ง๋ ฌํ ์ค์ ์ ํ๋ค.
passport๋ ์ฌ์ฉ์ ๋ฐ์ดํฐ๋ฅผ ์ง๋ ฌํํ๊ฑฐ๋ ์ญ์ง๋ ฌํํด ์ธ์ ์ ์ ๋ฌํ๋ค.
์ธ์ ์ ์์ถ๋ ํํ์ ์ง๋ ฌํ๋ ์ฌ์ฉ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๊ณ , ํด๋ผ์ด์ธํธ๋ก๋ถํฐ ๋ง์ง๋ง์ ๋ก๊ทธ์ธํ ์ฌ์ฉ์๋ฅผ ํ์ธํ๊ธฐ ์ํด ๋ฐ์ดํฐ๋ฅผ ๋ค์ ์๋ฒ๋ก ์ด๋์ํจ๋ค. ์ญ์ง๋ ฌํ๋ ์ฌ์ฉ์ ๋ฐ์ดํฐ๋ฅผ ์์ถ ๋ฒ์ ์ผ๋ก๋ถํฐ ๋ณต๊ตฌํ๋ฉฐ, ์ด ๋ฐ์ดํฐ๋ฅผ ํตํด ์ฌ์ฉ์ ์ ๋ณด๋ฅผ ํ์ธํ ์ ์๋ค.
- ์ง๋ ฌํ: ์์ถ๋ ๊ฐ๋ ํ์์ผ๋ก ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ๋ฐ๊พธ๋ ํ๋ก์ธ์ค์ด๋ค. ์ด ๋ฐ์ดํฐ๋ JSON, XML๊ณผ ๊ฐ์ ๋ค์ํ ํฌ๋งท์ ์ทจํ ์ ์๋ค. ์ฌ์ฉ์ ๋ฐ์ดํฐ๋ ๋จ์ผ ๋ฐ์ดํฐ๋ก ๋ณํ๋ผ HTTP ํธ๋์ญ์ ๋ด์์ ์ ๋ฌ๋ ์ ์๋ค.
Passport.js๋ ์ด ์ง๋ ฌํ ํ๋ก์ธ์ค๋ฅผ ์ํํ๊ณ ์ฌ์ฉ์ ๋ฐ์ดํฐ๋ฅผ ์ํธํํด ํด๋ผ์ด์ธํธ ๋ธ๋ผ์ฐ์ ์ ์ด ๋ฐ์ดํฐ๋ฅผ ์ธ์ ์ฟ ํค ์ค ์ผ๋ถ๋ก ์ ์ฅ์ํจ๋ค. ์ด ์ฟ ํค๋ ์ฌ์ฉ์ ์ ๋ณด๋ฅผ ํฌํจํ๊ณ ์๊ธฐ ๋๋ฌธ์ ๋ค์๋ฒ์ ์์ฒญ์ด ๋ฐ์ํ ๋, ์ด ์ฌ์ฉ์๊ฐ ์ด์ ์ ๋ก๊ทธ์ธ ํ์๋ค๋ ๊ฒ์ ์ ํ๋ฆฌ์ผ์ด์ ์๋ฒ์ ์๋ ค์ค๋ค.
passport.use(User.createStrategy()); //์ฌ์ฉ์์ ๋ก๊ทธ์ธ ์คํธ๋ํฐ์ง ์ค์
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser()); //์ง๋ ฌํ์ ์ญ์ง๋ ฌํ ์์
ํ๋๋ก ์ค์
์ด๋ ๊ฒ main.js์ ํ์ํ ์ฝ๋๋ฅผ ๋ค ์ถ๊ฐ์ํค๊ณ , ๋ง์ง๋ง ๋จ๊ณ๋ก ์ฌ์ฉ์ ๋ชจ๋ธ์ passport-local-mongoose์ ์ฐ๋์ํจ๋ค.
user.js ๋ชจ๋ธ ํ์ผ์ ์ด๋ ๊ฒ ์ถ๊ฐํ๋ค.
const passportLocalMongoose = require("passport-local-mongoose");
userSchema.plugin(passportLocalMongoose, {
usernameField: "id"
});
Mongoose ํ๋ฌ๊ทธ์ธ ๋ฉ์๋๋ฅผ ์ฌ์ฉํด userSchema๊ฐ passportLocalMongoose๋ฅผ ํจ์ค์๋์ ํด์ฑ๊ณผ ์ ์ฅ์ ์ฌ์ฉํ๋ค.
passportLocalMongoose๊ฐ id๋ฅผ ๋ก๊ทธ์ธ ํ๋ผ๋ฏธํฐ๋ก ์ฌ์ฉํ๊ฒํ๋ค.
์์ ์ฝ๋๊ฐ ์ถ๊ฐ๋๋ฉด Passport.js๋ ์๋์ ์ผ๋ก ํจ์ค์๋ ์ ์ฅ์ ๊ด์ฌํ๋ฉฐ, userSchema์์ password ์์ฑ์ ์์ ๋ฒ๋ ค๋ ๋๋ค. ์ด ํ๋ฌ๊ทธ์ธ์ด ์คํค๋ง๋ฅผ ์์ ํด์ hash์ salt ํ๋๋ฅผ password ํ๋ ๋์ ์ถ๊ฐ์ํจ๋ค.
++ํด์์ ์ํธ
ํ๋ ํด์ฑ ๊ธฐ์ ์ ์ฌ์ฉ์ ํจ์ค์๋๋ฅผ ๋ฐ์ ์ด๋ฅผ ์๋๋ก ๋ณต์ํ ์ ์๋ ํด์๋ก ๋ณํํ๋ค. ์ด ํด์๋ ๋ฌด์์์ ์ซ์์ ๋ฌธ์๋ก ๋ผ ์์ด ํ๋ฌธ๋ฐ์ดํฐ๋ณด๋ค ๋ ์์ ํ๊ฒ DB์ ์ ์ฅํ ์ ์๋ค. ํ์ง๋ง ํด์ปค๊ฐ ๊ทธ๊ฐ ์์ํ ํจ์ค์๋๋ฅผ ํด์ฑํด ๋น๊ตํ๋ค๋ณด๋ฉด ์ธ์ ๊ฐ๋ ์ค๋ฆฌ์ง๋ ํจ์ค์๋๋ฅผ ์์๋ผ ๊ฐ๋ฅ์ฑ์ด ์๋ค.
์ํธ๋ ์ด๋ฐ ์ทจ์ฝ์ ๊ณผ ์ธ์ฐ๊ธฐ ์ํด ๋์ ๋๋ค.
์ํธ๋ ์งง์ ๋๋ค ๋ฌธ์์ด์ด๋ฉฐ, ํ๋ฌธ ํจ์ค์๋๊ฐ ํด์ฑ๋๊ธฐ ์ ์ ํจ์ค์๋ ๋ค์ ๋ง๋ถ์ฌ์ง๋ค. ์ด๋ ๊ฒ ํ๋ฉด ํด์ปค๊ฐ ์ฌ์ฉ์์ ํจ์ค์๋๋ฅผ ์ ํํ ์ถ์ธกํ๋ค๊ณ ํด๋ ์ค๋ฆฌ์ง๋ ํจ์ค์๋์ ์ถ๊ฐ๋ ์ํธ ๊ฐ๋ ๊ฐ์ด ์ถ์ธกํด์ผํ๊ธฐ ๋๋ฌธ์ ํดํน์ด ๋ ์ด๋ ค์์ง๋ค.
Passport.js๋ ํด์ฑ๋ ํจ์ค์๋์ ์ํธ ๊ฐ์ DB์ ์ ์ฅํด ์ ํ๋ฆฌ์ผ์ด์ ๋ด์์ ํด์ฑ์ ํญ์ ์ํํ ์ ์๋๋ก ํ๋ค.
ํจ์คํฌํธ ๋ฑ๋ก ์ฌ์ฉ์ ์ํ Create ์ก์ ์์
์ฌ์ฉ์ ๊ณ์ ์์ฑ ์ ์ ์ํํ๋ bcrypt ํด์ฑ ํจ์ ๋์ ์ Passport.js๋ฅผ ์ฌ์ฉํ ๊ฒ์ด๋ค.
registerController๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ๋ณ๊ฒฝํ๋ค.

์๋ ์๋ create ์ก์ ์ ์ ๋ ๊ฒ ์์ ํ๋ค.
register ๋ฉ์๋๋ Passport.js์ ๋ธ๋ฆฐ ๊ฒ์ด๋ค.
์ค์ ๋ก ํ์ด์ง๋ฅผ ์ด์ฉํด ์ฌ์ฉ์๋ฅผ ๋ฑ๋ก์์ผ ๋ณด๋ฉด,

์ด๋ ๊ฒ salt์ hash๋ผ๋ ๋๊ฐ์ ์์ฑ์ด ์ถ๊ฐ๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
๋ก๊ทธ์ธ ์ ์ฌ์ฉ์ ์ธ์ฆ
userController.js ์ authenticate ์ก์ ์ ์๋กญ๊ฒ ๋ฐ๊พผ๋ค.
๋จผ์ ์๋จ์
const passport = require("passport")๋ก passport ๋ชจ๋์ ์์ฒญํ๋ค.

๊ทธ๋ฆฌ๊ณ ์ด๋ ๊ฒ authenticate ์ก์ ์ ์์ ํ๋ค.
passport redirect ๋ฐ ํ๋์ ๋ฉ์์ง ์ต์ ์ ์ฌ์ฉํ๊ธฐ ์ํด ์ง์ passport.authenticate๋ฅผ ํธ์ถํ๋ค.
๊ทธ๋ฆฌ๊ณ ํ์ฌ ๋ก๊ทธ์ธ ๋ ์ํ์์ ๋ํ๋ด๊ธฐ ์ํด ๋ก๊ทธ์ธ์ด ๋๋ฉด ๋์ด์ ๋ค๋น๊ฒ์ด์ ๋ฐ์ Login / Register๊ฐ ๋จ์ง ์๊ณ
ํ์ฌ ๋ก๊ทธ์ธํ ์ฌ์ฉ์ ์ ๋ณด๋ ๋ก๊ทธ์์ ๋ฌธ๊ตฌ๋ฅผ ๋์์ฃผ๋๋ก ํ๋ค.
๋จผ์ ํ์ฌ ๋ก๊ทธ์ธ์ด ๋์ด์๋์ง ์ฌ๋ถ์ ๋ก๊ทธ์ธํ ์ฌ์ฉ์ ์ ๋ณด๋ฅผ ์ ์ฅํ๋ ๋ณ์๋ฅผ main.js์์ flashMessages๋ฅผ ์ ์ํ ๋ฏธ๋ค์จ์ด ํจ์์ ์๋์ ๊ฐ์ด ์ถ๊ฐํ๋ค.

isAuthenticated() ๋ฉ์๋๋ Passport.js์์ ์ ๊ณต๋๋ฉฐ, ์ด๋ฅผ ํตํด ์ฌ์ฉ์๊ฐ ์ฟ ํค์ ์ ์ฅ๋ผ์๋์ง ํ์ธํ ์ ์๋ค. ์ด๋ loggedIn ๊ฐ์ true๋ false๊ฐ ๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ฌ์ฉ์์ ์ ๋ณด๋ฅผ ์ถ์ถํด currentUser ๋ณ์์ ํ ๋นํ๋ค.
์ด์ ๋ชจ๋ ํ์ด์ง ์์์ flashMessages์ ๋ง์ฐฌ๊ฐ์ง๋ก ํด๋น ๋ณ์๋ค์ ์ฌ์ฉํ ์ ์๊ฒ ๋๋ค.
๋ค๋น๊ฒ์ด์ ๋ฐ๋ฅผ ๋ณด์ฌ์ฃผ๋ viewํ์ผ์ธ layout.ejs ๋ ์ด๋ ๊ฒ ์์ ํ๋ค.

๊ทธ๋ผ ์ด์ ๋ก๊ทธ์ธ๋ ์ํ์์๋ ๋ค๋น๊ฒ์ด์ ๋ฐ๊ฐ

์ด๋ ๊ฒ ๋ณด์ธ๋ค.
๊ทธ๋ฆฌ๊ณ ๋ก๊ทธ์์ ๊ธฐ๋ฅ์ ์ํด์๋ ๋ Passport.js์์ ์ ๊ณตํ๋ logout ์ก์ ์ ์ฌ์ฉํ๋ค.
์ด ๋ฉ์๋๋ ํ์ฑ์ค์ธ ์ฌ์ฉ์ ์ธ์ ์ ์ญ์ ํ๋ค.

์ด๋ ๊ฒ ์ฝ๋๋ฅผ ์งฐ๋ค.
๊ทธ๋ฐ๋ฐ ํํ์ด์ง๋ก ๋ฆฌ๋ค์ด๋ ์ ์ด ๋ผ์ผํ๋๋ฐ, error.ejs๋ก ๋์ด๊ฐ๋ค. (๋ก๊ทธ์์์ ๋๋ค) ์ด ๋ฌธ์ ๋ ํด๊ฒฐํด์ผ ํ ๊ฒ ๊ฐ๋ค.
(+ 2021.11.10 16:15 ์์ )
redirectView ์ก์ ์ ์ถ๊ฐํ์ง ์์์ ์๊ธด ๋ฌธ์ ์๋ค.

์ด๋ ๊ฒ ์ถ๊ฐ ํ๋๊น ๋๋ค.
(์ฑ ์ ๋์์์๋๋ฐ ์ธ๋ฐ์๋ ๊ฑฐ ๊ฐ์์ ์๋ง๋ค์์๋๋ฐ ์ด๊ฒ ๋ฆฌ๋ค์ด๋ ์ ํ ํ์ด์ง๋ฅผ ์ง์ ํด์ฃผ๋ ์ก์ ์ด์๋ค..ใ )