使用 passport.js 制定使用 req.params 而不是 req.body 的策略

with passport.js make strategy what use req.params instead req.body

我制定了这个策略,我尝试通过 url 参数进行身份验证。它从 java 代码调用。

url 看起来像:http://localhost/mc/download/filename/user@server.com/secretpass

此策略:

passport.use('mc-login', new LocalStrategy({
    passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, email, password, done) { // callback with email and password from our form

    // find a user whose email is the same as the forms email
    // we are checking to see if the user trying to login already exists
    User.findOne({ 'local.email' :  req.params.uname }, function(err, user) {
        // if there are any errors, return the error before anything else
        if (err)
            return done(err);

        // if no user is found, return the message
        if (!user)
            return done(null, false, req.flash('loginMessage', 'No user found.')); // req.flash is the way to set flashdata using connect-flash

        // if the user is found but the password is wrong
        if (!user.validPassword(req.params.upass))
            return done(null, false, req.flash('loginMessage', 'Oops! Wrong password.')); // create the loginMessage and save it to session as flashdata

        // all is well, return successful user
        return done(null, user);
    });

}));    

我尝试在这段代码中调用它:

app.get('/mc/download/:fname/:uname/:upass',

        function(req, res, next) {
      passport.authenticate('mc-login', function(err, user, info) {
        if (err) { return next(err); }
        if (!user) { return res.redirect('/login'); }
        req.logIn(user, function(err) {
          if (err) { return next(err); }
          return res.redirect('/users/' + user.username);
        });
      })(req, res, next);
    }

    ,function(req, res){
    ...

但在信息变量中 return [stack=undefined,name="BadRequestError",message="Missing credentials"] 并且用户为空

如何制定允许使用 req.params 变量进行身份验证的策略

LocalStrategy 要求用户名和密码出现在 req.queryreq.body 中。如果其中任何一个不存在,策略验证处理程序将不会被调用(这就是为什么即使 passReqToCallback 它也不起作用)。

您可以通过添加一个额外的中间件来欺骗 Passport,使其认为它们是已设置的,该中间件从 URL 参数填充用户名和密码:

app.get(
  '/mc/download/:fname/:uname/:upass',
  function(req, res, next) {
    // Populate username and password before passing it on to Passport.
    req.query.username = req.params.uname;
    req.query.password = req.params.upass;
    next();
  },
  function(req, res, next) {
    passport.authenticate('mc-login', function(err, user, info) {
      if (err) { return next(err); }
      if (!user) { return res.redirect('/login'); }
      req.logIn(user, function(err) {
        if (err) { return next(err); }
        return res.redirect('/users/' + user.username);
      });
    })(req, res, next);
  }
);