똑같은 삽질은 2번 하지 말자
(Node.js) Serialize 와 Deserialize 로그인 정보 저장 본문
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하는 모습을 볼 수 있다
'Node' 카테고리의 다른 글
Mongoose 의 populate (0) | 2019.12.14 |
---|---|
(Node.js) password 암호화 모듈 Crypto(crypto.js에 대해) (0) | 2019.11.01 |
(Node.js)Sokcet 통신을 이용한 1:1 chat (0) | 2019.10.25 |
(Node.js)module.exports 와 exports 차이 (0) | 2019.10.18 |
(Node.js)database.collection is not a function (0) | 2019.10.05 |