passport로 로그인 구현

박용헌·2021년 8월 13일
0

nodejs

목록 보기
1/1

개요

  • passport는 노드용 인증 미들웨어이다.

  • 웹 애플리케이션에서는 다음과 같은 방법으로 로그인 할 수 있다.

    1. 아이디와 비밀번호를 사용하여 로그인(로컬 로그인)
    2. Facebook이나 Google과 같은 사이트의 계정을 이용하여 로그인
  • passport에서는 전략(Strategy)이라고 하는 인증 메커니즘을 이용하여 각각의 로그인 방법을 구현한다.


인증

  • 공식 문서에 따르면 다음과 같이 passport.authenticate()를 이용하여 인증을 요청할 수 있다.
app.post('/login', passport.authenticate('local', { successRedirect: '/',
                                                    failureRedirect: '/login' }));

또는 콜백함수 내부에서 passport.authenticate()를 호출할 수 있다.

app.post('/login', (req, res, next) => {
  passport.authenticate('local', (err, user, info) => {
    // code
    return req.login(user, callback);
  }) (req, res, next);
});
  • passport.authenticate()의 두 번째 인자의 콜백 함수를 custom callback이라고 한다.

  • custom callback을 사용하지 않으면 자동으로 req.login이 호출이 되지만 custom callback을 사용할 시 직접 req.login()을 호출하여야 한다. custom callback의 인수는 'local'에서 호출한 done함수에서부터 온다.

  • passport.authenticate()는 middleware object를 리턴하므로 (req, res, next)를 끝에 붙여 evoke해주어 요청-응답 주기를 유지해야 한다.


Strategy

  • passport라는 폴더를 만들어 그 안에 각각의 로그인 전략을 구현한 모듈을 미리 작성하여 exports한다. 그리고 exports한 모듈들을 index.js에서 불러와 실행해 놓는다.
// index.js
const passport = require('passport');
const local = require('./localStrategy');
const kakao = require('./kakaoStrategy');

module.exports = () => {
  local();
  kakao();
}
  • index.js 에서 exports한 모듈은 app.js에서 또 실행해줘야 한다.
// app.js
const passportIndex = require('./passport');
passportIndex();

localStrategy

// localStrategy.js
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;

passport.use(new LocalStrategy((username, password, done) => {
  // code
}));
  • new LocalStrategy()의 첫번째 인자인 콜백 함수를 verify callback이라고 부른다. verify callback은 로그인 자격조건을 인자로 받아 로그인 요청의 자격을 확인한다.

  • verify callback은 done함수를 호출할 수 있고, done()의 인자는 차례대로 에러, 성공한 경우, flash message(실패시 메시지)이다. flash message는 선택 사항이다.

return done(null, user)	// 자격이 유효한 경우
return done(null, false, { message: 'incorrect password' })  // 실패한 경우
  • done() 실행 이후 다시 passport.authenticate()로 돌아와 req.login(user, callback)을 실행한다. 이 때 사용자 객체(user)를 받으면 req.user에 user를 할당한다.

serializeUser

  • 한 번 로그인이 성공하면, 이후 쿠키를 통해 세션이 설정되고 유지되는데 serializeUser을 통해 user객체를 session에 저장할 수 있다. 이 때, 객체를 통째로 저장하기보다 가벼운 id만 저장하여 후에 deserializeUser를 통해 user객체를 복구할 수 있다.
    passport.serializeUser((user, done) => {
        return done(null, user.id);
    });
  • done()의 실행결과로 session객체 내부에 passport property가 생긴다. 이 property 안에 user.id가 담긴다.

deserializeUser

passport.deserializeUser((id, done) => {
  User.findOne({ where: { id } })
    .then(user => done(null, user))
    .catch(err => done(err));
});
  • 브라우저가 세션쿠키를 보내면(요청) app.js의 passport.session() 미들웨어가 id를 알아내고 deserializeUser를 실행하여 id를 넘겨준다. deserializeUser는 이 id로 데이터베이스를 조회한다.

  • 복구한 user의 정보는 req.user로 접근이 가능하다. 또한 req.isAuthenticated 프로퍼티가 true로 변경된다.


app.js

  • app.js에서 다음 미들웨어를 사용한다.
app.use(passport.initialize());	// passport 초기화
app.use(passport.session());	// 영구 로그인세션 사용시
  • passport.session()의 경우 세션을 받아야 하기 때문에 express session보다 아래에 위치해야 한다.
profile
안녕하세요 개발을 배우고 있습니다

0개의 댓글