Express Passport未通过我的策略

时间:2016-05-31 19:37:35

标签: angularjs express passport.js passport-local

我的Angular - Express + Passport行为有一种奇怪的行为。

在我的应用程序中,用户通过以下方式进行身份验证:AngularJS应用程序调用链接到NTML的外部服务,该服务返回多个信息,例如当前用户的电子邮件。 然后,AngularJS应用程序在我的Express后端(/rest/userProfile)上调用REST服务以获取用户的完整配置文件。那是我在后端验证用户的时候。

然而,与此同时,AngularJS应用程序(在其初始化期间)在我的后端调用其他几个REST api(例如检索/rest/config中的应用程序配置,以及在主页上显示的其他一些内容)。这些来电不受保护,通常在<{>>之前处理/rest/userProfile

换句话说,Express会话是由后端收到的第一个请求创建的,通常是/rest/config而不是/rest/userProfile(我认为这一点非常重要)。

在完成所有初始化之后,用户可以调用一些受保护的REST api,例如/rest/foo/。 但似乎有时,然后在后端无法识别用户,尽管请求包含Express cookie(connect.sid)。日志显示请求对象不包含passport属性。

如果我刷新浏览器的一两次,一切都开始正常工作,即用户最终被识别。在那之后,在某些时候,我可以重启我的浏览器,它可以直接工作而没有问题。

似乎如果我延迟所有请求(如/rest/config)以确保/rest/userProfile是服务器上收到的第一个请求,则一切正常(即用户将在受保护时正确识别)路由)。

  • 我的理解是正确的,因为与我当前的实现我必须将对/rest/userProfile的调用作为后端收到的第一个请求,因此Passport创建的会话将包含用户信息?
    • 如果是,我必须在实施中更改(参见下文)以使其工作,无论何时收到对/rest/userProfile的呼叫(当然在任何受保护路线之前)?
    • 如果不是,我的网站有什么问题?有任何线索吗?

代码

在我的index.js上,我设置了以下Express中间件:

app.use(session({
  secret: 'xxx',
  resave: true,
  saveUninitialized: true
}));
app.use(passport.initialize());
app.use(passport.session());

在我的主要路线JS文件:

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

passport.deserializeUser(function(username, done) {
  console.log('[deserialize username]', username);
  User.findOne({username: username}, function(err, user) {
    done(err, user);
  });
});

passport.use('ntml-strategy', new LocalStrategy({
  usernameField: 'mail',
  passwordField: 'password',
  passReqToCallback: true
},
function(req, username, password, done) {
  console.log('[ntml strategy]', username);
  User.findOne({username: username}, function(err, user) {
    if (err) {
      return done(err);
    } else if (user && user !== null) {
      return done(null, user);
    }
    // User does not exist in DB.
    // We should create a new user with data received from client.
    var newUser = new User({
      username: username,
      roles: ['user']
    });
    User.create(newUser, function(err, userSaved) {
      if (err) {
        return done(err);
      }
      return done(null, userSaved);
    });
  });
}));

// The REST api to get user profile
app.post('/rest/userProfile', passport.authenticate('ntml-strategy'), getUserProfile);

function getUserProfile(req, res) {
  var user = req.user;
  console.log('[getUserProfile]', user);
  if (!user) {
    return res.status(401).end();
  }
  res.json({
    username: user.username,
    roles: user.roles
  });
}

// In other file, another route:
app.get('/rest/foo/', isAuthenticated, getUserStuff);

function isAuthenticated(req, res, next) {
  if (!req.isAuthenticated()) {
    return res.status(401).end();
  }
  next();
}

function getUserStuff(req, res, next) {
  // Do stuff
}

User模型上,我设置了passport-local-mongoose

User.plugin(passportLocalMongoose, {
  usernameField: 'username',
  usernameUnique: true
});

请注意,删除该插件不会改变行为中的任何内容。

感谢。

对于版本:节点5.5,快递4.10.8,护照0.3.2,护照本地1.0.0和Angular 1.5。

0 个答案:

没有答案