똑같은 삽질은 2번 하지 말자

(Node.js) Serialize 와 Deserialize 로그인 정보 저장 본문

Node

(Node.js) Serialize 와 Deserialize 로그인 정보 저장

곽빵 2019. 10. 29. 16:45

Serialize Deserialize

로그인이 성공하면,

var LocalStrategy = require('passport-local').Strategy;

module.exports = new LocalStrategy({
    usernameField: 'email',
    passwordField: 'password',
    passReqToCallback: true // 이 옵션을 설정하면 아래 콜백 함수의 첫번째 파라미터로 req 객체 전달됨
}, function (req, email, password, done) {
    console.log('passport의 local-login 호출됨 : ' + email + ', ' + password);

    var database = req.app.get('database');
    database.UserModel.findOne({
        'email': email
    }, function (err, user) {
        if (err) {
            return done(err);
        }

        // 등록된 사용자가 없는 경우
        if (!user) {
            console.log('계정이 일치하지 않음.');
            return done(null, false, req.flash('loginMessage', '등록된 계정이 없습니다.')); // 검증 콜백에서 두 번째 파라미터의 값을 false로 하여 인증 실패한 것으로 처리
        }

        // 비밀번호 비교하여 맞지 않는 경우
        var authenticated = user.authenticate(password, user._doc.salt, user._doc.hashed_password);
        if (!authenticated) {
            console.log('비밀번호 일치하지 않음.');
            return done(null, false, req.flash('loginMessage', '비밀번호가 일치하지 않습니다.')); // 검증 콜백에서 두 번째 파라미터의 값을 false로 하여 인증 실패한 것으로 처리
        }

        // 정상인 경우
        console.log('계정과 비밀번호가 일치함.');
        return done(null, user); // 검증 콜백에서 두 번째 파라미터의 값을 user 객체로 넣어 인증 성공한 것으로 처리
    });

});

 

done 으로 serializeUser 에 정보를 넘겨준다.

serializeUser 메서드를 이용하여 사용자 정보를 Session 저장할  있다.

 

passport.serializeUser(function(user, done) {    
	console.log('serialize');    
	done(null, user);
});

serializeUser 메서드에서는 function(user,done) 이용해서 session 저장할 정보를 done(null,user) 같이 두번째 인자로 넘기면 된다. 이때 user 넘어오는 정보는 앞의 LocalStrategy 객체의 인증함수에서 done(null,user) 의해 리턴된 값이 넘어온다.  예제에서는  user 객체 전체를 사용자 session 저장하였다.

다음으로, node.js 모든 페이지에 접근할때, 로그인이 되어 있을 경우 모든 사용자 페이지를 접근할 경우,

deserilizeUser 발생한다. deserializeUser에서는 session 저장된 값을 이용해서, 사용자 Profile 찾은 , HTTP Request  리턴한다.

 

// 인증 후, 페이지 접근시 마다 사용자 정보를 Session에서 읽어옴.

passport.deserializeUser(function(user, done) {
    //findById(id, function (err, user) {
    console.log('deserialize');   
    done(null, user);
    //});
});

deserializeUser callback함수의 첫번째 인자로 넘어오는 내용”user” 세션에 저장된 사용자 정보이다.  예제에서는 session 해당 사용자의 정보를 저장하였기 때문에 별도의 변경없이 done(null,user) 이용해서 

그대로 session에서 읽은 내용을 리턴한다.

이렇게 리턴된 내용은 HTTP Request  “req.user” 값으로 다른 페이지에 전달된다.

설명이  복잡한데, 배경을 설명하면 다음과 같다. Session 사용자 정보를 저장하고자할 경우, 사용자 정보가 크다면, 메모리가 많이 소모되기 때문에, serializeUser시에, 사용자 id 같은  정보만 저장하도록 하고, 페이지가 접근될때 마다 deserilizeUser 수행되면,세션에 저장된 사용자 id 이용하여 데이타베이스에서 사용자 정보를 추가로 select해서 HTTP request 붙여서 리턴하는 형태를 사용한다.

실제로도 PassPort 공식 메뉴얼을 보면 다음과 같이 가이드를 하고 있다.

passport.serializeUser(function(user, done) {
          done(null, user.id);
});


passport.deserializeUser(function(id, done) {
          User.findById(id, function(err, user) {
          	done(err, user);
          });
});

 

serialize시에 session에서는 user.id 사용자 id값만 저장하고, deserialize시에는 session 저장된 id 이용해서, DB 매번 사용자 정보를 select하는 모습을   있다



Comments