2월 23일 자 학습 내용 정리입니다.
✅ Passport.js
Passport.js는 Express.js 어플리케이션에 간단하게 사용자 인증 기능을 구현하게 도와주는 패키지이다.
유저 세션 관리 및 다양한 로그인 방식 추가 기능을 지원한다.
Passport.js는 다양한 로그인 방식을 구현하기 위해 strategy라는 인터페이스를 제공한다.
strategy 인터페이스에 맞게 설계된 구현체를 그대로 passport에 붙이면 passport는 로그인 구현을 도와준다.
passport-google-oauth, passport-facebook, passport-twitter, passport-kakao, passport-naver 같이 SNS 계정을 통해서 바로 로그인할 수 있는 패키지 등 다양한 구현체들이 이미 존재하는데 그중 passport-local은 username, password를 사용하는 로그인의 구현체이다.
✏️ 예제 - 로그인 구현하기
로그인을 구현하는 방식은 다음과 같다.
- 로그인 화면 구성
- passport-local strategy로 로그인 구현
- passport.js 설정
- passport로 요청 처리
✔️ 로그인 화면 구성
...
form(action="/auth" method="post" onsubmit="return check()")
table
tbody
tr
td 이메일
td: input(type="text" name="email")
tr
td 비밀번호
td: input(type="password" name="password")
tr
td(colspan="2")
td: input(type="submit" name="로그인")
...
로그인 페이지를 구현한 코드이다.
POST 요청을 보내기 위해 form을 사용했고 입력받을 이메일, 비밀번호 칸을 생성했다.
✔️ 유효 값 체크
...
script.
function check() {
const email = document.querySelector('[name="email"]').value;
if (!email) {
alert("이메일을 입력해 주세요.");
return false;
}
const password = document.querySelector('[name="password"]').value;
if (!password) {
alert("비밀번호를 입력해 주세요.");
return false;
}
return true;
}
로그인 시에는 이메일과 비밀번호의 입력이 꼭 필요하기 때문에 이메일과 비밀번호를 둘 다 입력받았는지 확인한다.
✔️ strategy 생성
const config = {
usernameField: "email",
passwordField: "password",
};
const local = new LocalStrategy(config, async (email, password, done) => {
try {
const user = await User.findOne({ email });
if (!user) {
throw new Error("회원을 찾을 수 없습니다.");
}
if (user.password !== password) {
throw new Error("비밀번호가 일치하지 않습니다.");
}
done(null, {
shortId: user.shortId,
email: user.email,
name: user.name,
});
} catch (err) {
done(err, null);
}
});
passport-local을 사용하기 위해서는 먼저 Strategy를 생성하는데 이때 config 값을 전해준다.
passport-local이 username과 password를 사용해 사용자를 인증하기 때문에 인증할 때 쓰일 username이 email이고 password가 password임을 알려주는 것이다.
Strategy 생성 시 콜백함수에는 사용자로부터 받은 email, password 그리고 콜백함수인 done이 인자로 주어진다.
유저의 아이디가 있고 해당 유저의 비밀번호도 일치한다면 로그인은 성공한다.
로그인이 성공할 경우 done 함수의 첫 번째 인자는 null, 두 번째 인자는 입력받은 사용자의 정보를 전해준다.
로그인이 실패할 경우 done에 err를 넘겨준다.
쉽게 말해 done의 첫 번째 인자는 에러 발생 여부, 두 번째 인자는 사용자 정보의 전달 여부라고 생각하면 된다.
✔️ passport.js 설정
const local = require('./strategies/local');
passport.use(local);
작성한 strategy를 사용할 수 있도록 passport.use로 선언해야 한다.
passport.use로 strategy를 사용할 수 있게 선언한 뒤 passport.authenticate를 사용해 해당 strategy로 로그인 요청을 처리할 수 있다.
이 경우 passport.use 부분과 strategy 생성 부분을 합쳐 작성하기도 한다.
passport.use(new LocalStrategy(
async function(username, password, done) {
await User.findOne({ username: username }, function (err, user) {
if (err) { return done(err); }
if (!user) { return done(null, false); }
if (!user.verifyPassword(password)) { return done(null, false); }
return done(null, user);
});
}
));
✔️ 로그인 요청 처리
--- routes/auth.js ---
router.post("/", passport.authenticate("local"));
--- app.js ---
const session = require("express-session");
app.use(
session({
secret: "secret",
resave: false,
saveUninitialized: true,
}),
);
app.use(passport.initialize());
app.use(passport.session());
app.use("/auth", authRouter);
passport.authenticate 함수를 http 라우팅에 연결하면 passport가 자동으로 해당 strategy를 사용하는 request handler를 생성한다.
이때 express-session과 passport.session()을 사용하면 passport가 로그인 시 유저 정보를 세션에 저장하고 가져오는 동작을 자동으로 수행해 준다.
✔️ session 활용
passport.serializeUser((user, callback) => {
callback(null, user);
});
passport.deserializeUser((obj, callback) => {
callback(null, obj);
});
session을 이용해 user를 사용할 때에는 serializeUser와 deserializeUser를 설정해 주어야 한다.
serializeUser는 user 객체를 전달받아 세션에 저장한다.
이로 인해 페이지 이동 시에도 로그인 정보가 유지될 수 있다.
deseializeUser는 세션에 저장된 정보를 통해 user 정보를 불러온다.
✔️ 로그아웃
router.get('/logout', ... {
req.logout();
res.redirect('/');
});
로그아웃의 경우 req.logout() 함수를 통해 세션의 로그인 정보를 삭제하여 구현할 수 있다.
✔️ 로그인 확인 미들웨어
function loginRequired(req, res, next) {
if (!req.user) {
res.redirect("/");
return;
}
next();
}
app.use("/posts", loginRequired, postsRouter);
로그인 확인 미들웨어는 특정 구역에 로그인을 필수로 설정하고 싶을 경우 미들웨어를 사용하여 로그인 여부를 체크한다.
🔍 참조
passport로 로그인하기 https://www.zerocho.com/category/NodeJS/post/57b7101ecfbef617003bf457
passport-local https://www.passportjs.org/packages/passport-local/

'엘리스 AI 트랙 4기 > elice AI track' 카테고리의 다른 글
[6주차] JSON Web Token (0) | 2022.02.25 |
---|---|
[6주차] Session과 Session Store (0) | 2022.02.23 |
[6주차] crypto와 회원가입 구현하기 (0) | 2022.02.23 |
[5주차] Express.js + Mongoose로 Pagination 구현하기 (0) | 2022.02.19 |
[5주차] Pug와 Async Request Handler, PM2 (0) | 2022.02.19 |
댓글