只是不能让Passport.js工作

时间:2014-05-09 16:10:20

标签: javascript node.js mongodb coffeescript passport.js

编辑:对不起,现在已经很久了,在已编译的JS中添加了!我还添加了Kevs的建议。

我正在开发一个MEAN堆栈应用程序(MongoDB,ExpressJS,Angular,NodeJS)并且玩得很开心,尤其是咖啡脚本。我的问题是,每次返回{success:false}时,我都无法使passport.js工作。当我在我的LocalStrategy函数中执行console.log时,它似乎从未被调用过。知道为什么吗?

一些片段

server.coffee(主文件)

...
Account = mongoose.model 'account'

passport.use 'local-login', new LocalStrategy (_username, password, done) ->
  Account.findOne {username:_username}, (error, user) ->
    if error
      done error
    if not user
      done null, false, {message:'Incorrect username.'}
    done null,user
passport.serializeUser (user, done) ->
  console.log 'serialize user'
  if user
    done null, user
passport.deserializeUser (id, done) ->
  Account.findOne({_id:id}).exec (error, user) ->
    if user
      return done null, user
    else
      return done null, false
...

编译js

...
Account = mongoose.model('account');

  passport.use('local-login', new LocalStrategy(function(_username, password, done) {
    return Account.findOne({
      username: _username
    }, function(error, user) {
      if (error) {
        done(error);
      }
      if (!user) {
        done(null, false, {
          message: 'Incorrect username.'
        });
      }
      return done(null, user);
    });
  }));

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

  passport.deserializeUser(function(id, done) {
    return Account.findOne({
      _id: id
    }).exec(function(error, user) {
      if (user) {
        return done(null, user);
      } else {
        return done(null, false);
      }
    });
  });
...

routes.coffee

...
  app.post '/login', (request, result, next) ->
    auth = passport.authenticate 'local-login', (err, user) ->
      if err
        next err
      if not user
        result.send {success:false}
      request.logIn user, (err) ->
        if err
          next err
        result.send {success:true}
    auth request, result, next
...

编译js

...
    app.post('/login', function(request, result, next) {
      var auth;
      auth = passport.authenticate('local-login', function(err, user, info) {
        if (err) {
          next(err);
        }
        if (!user) {
          result.send({
            success: false
          });
        }
        return request.logIn(user, function(err) {
          if (err) {
            next(err);
          }
          return result.send({
            success: true
          });
        });
      });
      return auth(request, result, next);
    });
...

mongo.coffee

...
  accountSchema = mongoose.Schema {
    username: String
    firstname: String
    lastname: String
    email: String
  }

  Account = mongoose.model 'account', accountSchema

  Account.find({}).exec (error, collection) ->
    if collection.length == 0
      Account.create {
        username: 'alex'
        firstname: 'Alex'
        lastname: 'Hxxx'
        email: 'axxxxx@gmail.com'
      }
...

编译js

  module.exports = function(config) {
    var Account, accountSchema, db;
    mongoose.connect("mongodb://" + config.db_host + "/" + config.db_name);
    db = mongoose.connection;
    db.on('error', function() {
      return console.error('Database connection error');
    });
    db.once('open', function() {
      return console.log('Database connection established');
    });
    accountSchema = mongoose.Schema({
      username: String,
      firstname: String,
      lastname: String,
      email: String
    });
    Account = mongoose.model('account', accountSchema);
    return Account.find({}).exec(function(error, collection) {
      if (collection.length === 0) {
        return Account.create({
          username: 'alex',
          firstname: 'Alex',
          lastname: 'Hxxx',
          email: 'axxxxxxxxx@gmail.com'
        });
      }
    });
  };

express.coffee

...
  app.use cookie-parser(config.cookiesecret)
  app.use session {secret: config.sessionsecret}
  app.use passport.initialize()
  app.use passport.session()
  app.use bodyParser()
...

编译js

...
  app.use(cookie-parser(config.cookiesecret));
  app.use(session({
    secret: config.sessionsecret
  }));
  app.use(passport.initialize());
  app.use(passport.session());
  app.use(bodyParser());
...

我的角度登录控制器

app.controller 'loginCtrl', ['$scope', '$http', ($scope, $http) ->
  $scope.login = (username, password) -> 
    $http.post('/login', {username: username, password: password}).then (response) ->
      console.log response.data
      if response.data.success
        console.log "Logged in as #{username}"
      else
        console.log "Failed to login as #{username}"
]

编译js

  app.controller('loginCtrl', [
    '$scope', '$http', function($scope, $http) {
      return $scope.login = function(username, password) {
        return $http.post('/login', {
          username: username,
          password: password
        }).then(function(response) {
          console.log(response.data);
          if (response.data.success) {
            return console.log("Logged in as " + username);
          } else {
            return console.log("Failed to login as " + username);
          }
        });
      };
    }
  ]);

和我的登录表单(jade):

h3 Login
  form(ng-controller="loginCtrl")
    .row
      .columns.small-12.large-12
        form
          label Username
          input(placeholder="username",name="username",type="text",ng-model="username")
          label Password
          input(placeholder="password",name="password",type="password",no-model="password")
          div(align="center")
            button.button(ng-click="login(username,password)") Login
            span  
            a.button(href="/user/Register") Register

示例用户被正确创建,因此猫鼬没问题,并且在我开始使用护照之前都已设置好。我跟着几个不同的教程,这让我发疯了!

3 个答案:

答案 0 :(得分:3)

你没有设置passport.use的初始参数,并将req传回回调 - 例如 - 来自我的代码:

passport.use('local-login', new LocalStrategy({
    // by default, local strategy uses username and password, we will override with email
    usernameField : 'email',
    passwordField : 'password',
    passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, email, password, done) {

    // asynchronous
    // User.findOne wont fire unless data is sent back
    process.nextTick(function() {

      db.Account.findOne( { ...

然后您可以使用以下方式进行身份验证:

passport.authenticate('local-login',function(err,user,info){

在您的情况下,您正在致电passport.authenticate' local'所以你在passport.use中的第一个参数应该是' local'这样它就可以调用正确的策略

答案 1 :(得分:0)

我的护照策略几乎完全相同,但有一个例外:将用户序列化为_id属性。我怀疑这可能是问题,因为在你的deserialize方法中你直接使用_id,但在序列化中传递done null, user

passport.serializeUser (user, done) ->
  if user
    done null, user?._id

答案 2 :(得分:0)

我认为它比这里发布的答案更简单。您需要if error?if not user? ?。如果没有?,它会进行真/假检查,但是使用?s会进行空检查,这是你想要的。

试试这段代码:

Account = mongoose.model 'account'

passport.use 'local-login', new LocalStrategy (_username, password, done) ->
    Account.findOne {username:_username}, (error, user) ->
        if error?
            done error,null
        else if not user?
           done null, false, {message:'Incorrect username.'}
        else
           done null,user
passport.serializeUser (user, done) ->
   console.log 'serialize user'
   if user?
       done null, user._id
passport.deserializeUser (id, done) ->
    Account.findOne({_id:id}).exec (error, user) ->
        if user?
            return done null, user
        else
            return done null, false