민자의 지식창고

passport.js(작성중) 본문

개발노트/NodeJs

passport.js(작성중)

전지적민자시점 2021. 11. 3. 16:36

NodeJs에서 인증을 위한 미들웨어 passport.js

 로그인방식이 소셜네트워킹이 증가하면서 페이스북, 네이버, 카카오 인증방법이 많아 졌다.

 이런 SNS or OAuth를 제공해주는 API를 제공하는 서비스들은 이제 접근을 제어하는 방식으로 토큰 기반의 증명서를 요구하고 있습니다. 

 

strategy에 따른 요청에 인증하기 위한 목적

post 요청으로 받은 이메일이나 패스워드등의 유저 데이터를 이용하여, express의 라우터에서 정보를 받는다.

 

Authenticate Flow는 아래와 같습니다.

1. Request.body 안에 들어온 data 들에 대해 인증을 실행한다.

2. (인증 실행)하면, 로컬전략을 통과하여 사용자를 검증한다.

3. (로컬전략 실행) serialize를 거쳐, 최종적으로 세션 ID 쿠기 만들어서, response haeder에 담겨진다

4. (serailizeUser 실행) 브라우저가 이 세션ID를 쿠키로 저장했다가, 요청시에 쿠키에 담아서 보내기 떄문에 서버에서 사용자임을 인식한 결과를 보낸다. 

5. deserializeUser 실행


과정에 대해서 상세하게 보겠습니다.

1. 인증 실행

passport.authenticate('local', (err, user, info) => callback( return req.login()) )

local를 넣으면 로컬전략모듈을 실행합니다. 실패시에 callback의 error 객체가 반환되고 user는 false로 값이 반환이 됩니다. info는 additional detail으로 실패 이유가 들어옵니다. 

 

2.로컬전략의 실행

passport.use(new LocalStrategy({}, (email, password, done => { verification 내용 })

ID와 Password가 맞는지 검증이 목적입니다.

db에 저장된 user의 정보와 입력받은 데이터가 같은지 비교하게 됩니다.

개발자가 스스로 작성하게 되며 Passport 로컬전략은 검증결과를 세션에 저장하고 쿠키를 주고 받을수 있도록 자동화 틀을 제공해줍니다

 

 Username과 Password 변수명 설정

 passport.authenticate()는 localStrategy.js로 username과 password를 보내줍니다. 이 두값은 각 defualt값이 설정되어 있는데, 이 변수명을 Email로 변경합니다. 굳이 username을 email로 변경할 필요가 없다면 해당 인자를 주지 않아도 됩니다.

passport.use(new LocalStrategy({
    passReqToCallback: true,
    req: express.Request, 
    usernameField: 'email',
    passwordField: 'password',
  }, async (req, email, password, done) => {
    try { 
        cosnt exuser = # User DB 정보
        done(null, exUser)
     } catch (error){
     	done(error)
     }

Username의 검증

 사용자가 입력한 정보( email과 password)를 갖고 Verification을 합니다. email은 DB 조회하여 DB에 저장된 사용자인지 검증하고, Password는 암호화 모듈을 사용하여 검증한다.

 만약, 사용자가 없다면 done()으로 authenticate Callback에 인자를 전달 할 값을 적어 줍니다.

 

done의 인자는 순서대로 authenticate의 Callback에 매칭된다.
done => authenticate callback
null => error
false => user
{reason : "존재하지 않는 사용자입니다"} => info
#예시
 done(null, false, { status: 404, message: config.msgPwNotMatch});
 done(null, false, { status: 404, message: config.msgNotUser});

db조회 결과 user가 없으면, error는 null을 보내줍니다. db 정보가 없기 때문에 오류가 아닌 null를 보내줍니다.

user에 false를 보내서 사용자가 없음을 알려줍니다. info는 db에 없는 존재 메세지를 줍니다.

 

 Password의 검증

 password의 경우 사용하고 있는 암호화모듈을 통해서 검증을 합니다. bcrypt or crypto 같은 암호화모듈을 사용합니다.

 db의 저장된 비밀번호와 일치하는가 검증을 하는 것이 핵심입니다. 

 

exports.pbkdf2Compare = async (password, originPassword, salt) => {
    const hash = await this.pbkdf2Async(password, salt);
    if (originPassword === hash) {
        return true;
    } else {
        return false;
    }
}

 

728x90