Javascript Passport.js用户登录&;认证

Javascript Passport.js用户登录&;认证,javascript,node.js,express,passport.js,Javascript,Node.js,Express,Passport.js,在过去的几天里,我一直在使用Passport.js开发我的第一个用户登录和身份验证系统。够尴尬的是,我已经完成了它,它的工作正如预期的那样。问题是,尽管我在网上读了很多文章并查看了数十个示例,但我似乎并不完全理解代码本身。我完全理解它背后的过程以及为什么会发生这样的事情。如果您能为我澄清代码的某些部分,我将不胜感激。这是工作代码,存储在my app.js文件中: // Passport session setup passport.serializeUser(function (user, do

在过去的几天里,我一直在使用Passport.js开发我的第一个用户登录和身份验证系统。够尴尬的是,我已经完成了它,它的工作正如预期的那样。问题是,尽管我在网上读了很多文章并查看了数十个示例,但我似乎并不完全理解代码本身。我完全理解它背后的过程以及为什么会发生这样的事情。如果您能为我澄清代码的某些部分,我将不胜感激。这是工作代码,存储在my app.js文件中:

// Passport session setup
passport.serializeUser(function (user, done) {
    done(null, user._id);
});

passport.deserializeUser(function (id, done) {
    User.findById(id, function(err, user) {
        done(err, user);
    });
});

// Use the Local Strategy within passport
passport.use(new LocalStrategy(function (username, password, done) {
    User.findOne({ username: username }, function(err, user) {
        if (err) {
            return done(err);
        }

        if (!user) {
            return done(null, false, { message: 'Unknown user: ' + username});
        }

        user.comparePassword(password, function(err, isMatch) {
            if (err) {
                return done(err);
            }

            if (isMatch) {
                return done(null, user);
            } else {
                return done(null, false, { message: 'Invalid Password' });
            }
        });
    });
}));

var app = module.exports = express();

app.configure(function () {
    app.set('views', path.join(__dirname + '/views'));
    app.set('view engine', 'html');
    app.engine('html', hbs.__express);
    app.use(express.logger());
    app.use(express.cookieParser());
    app.use(express.bodyParser());
    app.use(express.methodOverride());
    app.use(express.session({ secret: 'xxx' }));    
    app.use(passport.initialize());
    app.use(passport.session());
    app.use(app.router);
    app.use(express.static(path.join(__dirname + '/public')));

});
我使用的是MongoDB(用户mongoose模型)。另外,为了在数据库中存储密码,我目前正在使用bcrypt

我认为这里我不理解的最关键的部分是done回调函数。我可以理解,它只是传递一些值,我知道很多,要知道它的第一个参数是错误,第二个参数是数据。不过,我并没有完全理解它,因为我还没有专门提供一个参数。例如,如果我有这样一个函数:

// Random Function
var randomFunction = function (a, b, done) {
    done(a, b);
};

// Then I would call the randomFunction providing my own **done**
randomFunction('Random', 'Words', function(a, b) { return a + b; });
不过,在我的示例中,我并不是指定done回调的人。它只是一个必需的回调函数参数,还是与普通中间件中的下一个函数相同,例如:

function middleware (req, res, next) {
    next(req.user); // pass the req.user to next middleware
}
另外,Passport.js在哪里绑定它处理的用户?它是否将其绑定到请求用户?我如何将其传递给某些视图,例如显示用户名

我期待着您的反馈


谢谢大家!

完成回调

请看以下代码:

verify
是策略将用于验证用户的功能,您已在此处指定该功能:

passport.use(new LocalStrategy(function (username, password, done) {
    // your verification code here
}));
在策略的后面部分,您可以找到从上述步骤调用verify函数的方法:

this._verify(username, password, verified);
现在,您可以看到
username
password
done==verified
来自何处。稍后在代码中,您将使用(err、user、info)参数调用
done
回调。简单地说,
done
需要完成用户验证的异步过程

请求用户和视图

是的,关于
req.user
,您是对的。因此,您可以通过两种方式将其传递给视图:

  • 作为
    res.render
    函数的参数

  • 使用
    res.locals
    作为某种上下文提供程序(现在用户对象将在
    app.router
    中定义的所有视图中可用)


  • 非常感谢您的反馈!据我所知,done是一个回调函数,用于从中间件返回信息。所谓信息,我指的是3个参数(错误、用户、信息)。基本上,我能把完成的回调看作是(高级的方式)返回那个特定的中间件吗?如果我用正确的方式理解你的问题,No.<代码> do/<代码>只用于向下一级提供一些数据。调用
    done()
    后,您的验证代码将以正常方式执行,这就是为什么您应该使用
    返回done(err)
    停止执行验证代码。这是异步内容的常见情况。这就是我的意思^^我想我的回答有点模棱两可:)非常感谢您的反馈,我非常感谢!
    this._verify(username, password, verified);
    
    res.render('some-template', { name: req.user });
    
    // before app.use(app.router);
    app.use(function(req, res, next) {
       res.locals.user = req.user;
       next();
    });