개발자의 logs
<개발공부, 개공> Passport, Passport-local 개념정리 본문
오늘은 어제 Oauth 2.0에 이어서 Passport 개념정리를 해보려고 한다.
참고로 Passport도 부트캠프내에서 다뤄본 적은 있다 (Google)
그럼 스타뜨 !!
Passport란 무엇인가?
Passport.js는 인증 요청을 처리해주는 Node.js의 인증 미들웨어이다.
기본적인 로그인 방법은 username과 password를 일치하여 확인하는 방식이지만, 최근 SNS의 증가로 Facebook과 Twitter에서 OAuth를 제공함에 따라 SNS들의 계정을 가지고 서비스를 가입하고 인증하는 방법이 생겼다.
<참고>
- Express.js 애플리케이션에 간단하게 사용자 인증 기능을 구현하게 도와주는 패키지이다.
- 유저 세션 관리 및 다양한 로그인 방식 추가할 수 있다.
OAuth에 대한 설명은 이전 게시물 참고!!
2022.08.28 - [개발 공부지식/*개발 공부*] - <개발공부, 개공> OAuth 2.0 개념정리.
Passport.js는 이러한 기본적인 로그인과 OAuth 인증방법을 제공하는 패키지로, 인증 과정을 Strategy이라는 이름으로 관리한다.
passport-local
- passport는 다양한 로그인 방식을 구현하기 위해 strategy라는 인터페이스를 제공한다.
- strategy는 passport가 로그인 방식을 어떻게 처리할지에 대한 인터페이스를 미리 설계한 거다.
- strategy 인터페이스에 맞게 설계된 다양한 구현체들이 있다. (facebook, google,...) 자연스럽게 login flow를 구현할 수 있게 도와준다.
- passport-local은 username, password를 사용하는 로그인의 구현체이다.
로그인 기능 구현하기
로그인 화면 구성
...
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="로그인")
...
...
script.
function check() {
const email = document.querySelector('name=["email"]').value;
if (!email) {
alert("이메일을 입력 해 주세요");
return false;
}
const password = document.querySelector('name=["password"]').value;
if (!email) {
alert("비밀번호를 입력 해 주세요");
return false;
}
return true;
}
passport-local strategy로 로그인 구현
/passport/strategies/local.js
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) { // 평문인 password가 아닌 hash값을 사용해야 된다.
throw new Error("비밀번호가 일치하지 않습니다.");
}
// 세션에 저장되는 유저 정보의 최소화
done(null, {
shortId: user.shortId,
email: user.email,
name: user.name,
});
} catch (err) {
done(err, null);
}
});
- 이메일, 비밀번호, 완료 처리하는 콜백 함수로 구성
- config값과 Authenticate를 사용한다.
- strategy 안에서 로그인 처리가 되어야 한다.
- 로그인 처리 후 어떤 데이터를 보낼지 결정하면 된다.
Passport.js 설정하기
/passport/index.js
const local = require('./strategies/local');
passport.use(local);
- 작성 한 strategy를 passport.use를 이용해 사용하도록 선언해야 한다.
- passport.use를 이용해 strategy를 사용하도록 선언한 후 passport.authenticate를 사용해 해당 strategy를 이용해 요청을 처리할 수 있다.
Passport.js로 post 요청 처리하기
// --- routes/auth.js ---
// router.post('/', passport.authenticate('local'), (req, res, next) => { res.redirect('/'); });
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를 설정해 주어야 한다. → 세션에 user 정보를 변환하여 저장하고 가져오는 기능을 제공해 준다.
- ex) 회원 id만 세션에 저장하고, 사용 시 회원정보를 디비에서 찾아서 사용
- 세션 사용 시 위 두 함수를 작성하지 않으면 passport 로그인이 동작하지 않는다.
serializeUser/deserializeUser
- passport는 세션에 최소한의 인증 정보만 저장한다. 로그인 한 뒤 세션에 데이터를 저장할 때 어떤 정보를 저장할지를 결정하는 함수가 serizliseUser이다.
- 반대로 세션에 저장한 데이터로 로그인한 유저 정보를 복구하는데 이걸 결정하는 함수가 deserializeUser다.
로그아웃
router.get('/logout', ... {
req.logout();
res.redirect('/');
});
- passport는 req.logout 함수를 통해 세션의 로그인 정보를 삭제하여, 로그아웃 기능을 구현할 수 있다.
로그인 확인 미들웨어
function loginRequired(req, res, next) {
// 미 로그인
if (!req.user) {
res.redirect('/');
return;
}
next();
}
// ----- app.js -----
app.use('/posts', loginRequired, postsRouter); // 로그인되어 있어야지만 post 할 수 있도록 설정
- 로그인을 필수로 설정하고 싶을 경우, 미들웨어를 사용하여 체크할 수 있다.
'개발 공부지식 > *개발 공부*' 카테고리의 다른 글
React Hooks 란 무엇인가? (0) | 2022.09.29 |
---|---|
<개발공부, 개공> TypeScript란 무엇인가? TypeScript를 쓰는 이유 (0) | 2022.08.31 |
<개발공부, 개공> OAuth 2.0 개념정리. (0) | 2022.08.28 |
기술면접 준비 Node.js 50문 (0) | 2022.08.24 |
<개발공부, 개공> Nest.js란 무엇인가? (0) | 2022.08.12 |
Comments