登入-Node部分

以jwt(json web token)+passport做處理

以下將一些重點的部分記錄下來。

passport.use(local); 使用localStrategy

app.use(passport.initialize()); 在express(app)內初始化

module.exports = new LocalStrategy({
  usernameField : 'email'
}, function(email, password, done) {
  Users.forge().query({where:{email:email}}).fetchOne().then(function(user) {
    if(!user) return done(null, false, { message: 'Email ' + email + ' not found'});
    user.comparePassword(password, function(err, isMatch) {
      if(isMatch) {
        return done(null, user);
      } else {
        return done(null, false, { message: 'Invalid email or password'});
      }
    });
  });
});

表示進來做驗證的參考是email和password
在這邊需要做兩件事:
1.用email把這個使用者從某處撈出來(我在這邊是用bookshelfjs從postgres撈)
2.比對密碼是否正確(正常來說你的db密碼應該要加密,這邊comparePassword內部我是用bcrypt做處理。)

comparePassword: function (candidatePassword, cb) {
    bcrypt.compare(candidatePassword, this.attributes.encrypted_password, function (err, isMatch) {
      if (err) return cb(err);
      cb(null, isMatch);
    })
}

大致如上

exports.postLogin = function (req, res, next) {
  // Do email and password validation for the server
  passport.authenticate('local', function (err, user, info) {
    if (err) return next(err);
    if (!user) {
      return res.status(401).send({
        info: info.message,
        data: {}
      });
    }

    var token = jwt.encode({ id: user.attributes.id}, tokenSecret);
    return res.json({ token : token,user: user.toJSON() });
  })(req, res, next);
};

app.post('/api/login', auth.postLogin);

在這邊是經過localStrategy後要傳回給user的結果,如果在Strategy內有error,找不到使用者等等的問題也是在這邊做處理。 如果一切安好的話,就可以用jwt把判別使用者的資訊傳回去給用戶,我在這裡只塞了user_id.

一般找到的說明都會用passport.session,透過session和cookie來做登入動作。 我在這邊由於是要讓mobile和React用相同的登入方式,所以就用了jwt來做, 但假使你也要跟我一樣這樣做的話,要幫你的網站做SSL加密(走https協定)