2016-08-30 4 views
0

Я разрабатываю модуль аутентификации для своего приложения. Когда имя пользователя и пароль отправляются в «/ admin/login», Api вызывает функцию входа в систему Auth. Далее я использую модель mongoose для запроса от MongoDb и возврата найденного объекта к переменной.NodeJs, получающий объект обратного вызова

auth.controller.js

var jwt = require('jwt-simple'); 
var bcrypt = require('bcrypt'); 
var User = require('../models/user.model.js'); 
var secret = require('../config.js').jwt_secret; 
var auth = { 
login : function (req, res) { 

    var username = req.body.username; 
    var password = req.body.password; 

    if (username === '' || password === '') { 
     res.status(401).json({message : 'Invalid Credentials'}); 
     return; 
    } 

    var dbUserObj = auth.validate(username, password); // receives the User object returned from callback 

     console.log(dbUserObj); //displays 'undefined' 

    if (!dbUserObj) { 

     res.status(401).json({message : 'Invalid Username or Password'}); 
     return; 
    } 

    if (dbUserObj) { 
     console.log('user found'); 
     res.json(genToken(dbUserObj)); 
    } 
}, 

validate : function (user, pass) { 
     User.findOne({username : user}, function (err, user) { 
     if (err) { 
      return; 
     } 
     if (user==null) { 
      console.log('no user found'); 
      return; 
     } else { 

      bcrypt.compare(pass, user.password, function (err,result) { 
      if (result == true) { 
       return user; 
      } 
     }); 
     } 

     }); 
} 
} 


function genToken (user) { 
    var expires = expiresIn(7); 
    var token = jwt.encode({exp : expires},secret); 
    return { 
    token : token, 
    exp : expires, 
    user: user 
    } 
} 

function expiresIn (t) { 
var dateObj = new Date(); 
return dateObj.setDate(dateObj.getDate() + numDays); 
} 

module.exports = auth; 

Переменная dbUserobject получает объект пользователя, возвращенное функцией проверки. Но если я запишу эту переменную, она отобразит «undefined» . Я знаю, что есть проблема обратного вызова, что следующие строки кода запускаются и после обратного вызова возвращается объект. Инициализируется переменная dbUserObject и всегда отправляет ответ «Недопустимое имя пользователя или пароль», поскольку dbUserObject становится не определено. Я пробовал несколько вещей, но не мог разобраться.

Как я могу заставить это работать так, как будто он сначала получает DbUserObj, а затем решает, отправлять ли недействительный ответ или генерировать токен Json Web.

Спасибо,

ответ

0

Поскольку существует проблема синхронизация и Асинхронного функция, как ваш auth.validate ведут себя, как асинхронные не ждать результата, благодаря которому пользователю объект получения неопределенным вы можете решить эту проблему с помощью Promise попробовать этот

var auth = { 
login : function (req, res) { 

    var username = req.body.username; 
    var password = req.body.password; 

    if (username === '' || password === '') { 
     res.status(401).json({message : 'Invalid Credentials'}); 
     return; 
    } 

     auth.validate(username, password) 
     .then(function(dbUserObj) { // `validate` returns a promise 
     console.log(dbUserObj); // Log the value once it is resolved 
       if (!dbUserObj) { 

        res.status(401).json({message : 'Invalid Username or Password'}); 
        return; 
       } 

       if (dbUserObj) { 
        console.log('user found'); 
        res.json(genToken(dbUserObj)); 
       } 

     console.log(dbUserObj); //displays 'undefined' 

     }).catch(function(v) { 
     // Or do something else if it is rejected 
     // (it would not happen in this example, since `reject` is not called). 
     }); 





}, 

validate : function (user, pass) { 
     return new Promise(function(resolve, reject) { 

      User.findOne({username : user}, function (err, user) { 
      if (err) { 
       return; 
      } 
      if (user==null) { 
       console.log('no user found'); 
       return; 
      } else { 

       bcrypt.compare(pass, user.password, function (err,result) { 
       if (result == true) { 
        return user; 
       } 
      }); 
      } 

      }); 
     // Only `delay` is able to resolve or reject the promise 
     setTimeout(function() { 
      resolve(user); // After 3 seconds, resolve the promise with user 
     }, 3000); 
     }); 
    } 
} 
+0

Wasiq, благодарю вас за это. Теперь у меня есть идея, но не могли бы вы рассказать о задержке? Почему требуется задержка? Получаю ли я пользователя без промедления? Если мне придется использовать задержку, почему я не должен использовать обратный вызов с задержкой? –

+0

как «обратный вызов» - это то же самое, что и «обещание», но обещание - более управляемый код. Вы также можете использовать без задержки. Я предлагаю вам использовать обещание «bluebird» в вашем узле, а также не использовать эту две функции в методе 'auth', чтобы сделать отдельную функцию или как' service' для лучших практик. –

+0

Как насчет библиотеки Promise.js? Я проверил голубую птицу, у нее проблемы с совместимостью. –

Смежные вопросы