简体   繁体   English

Passport.js用户登录和身份验证

[英]Passport.js User Login & Authentication

For the past few days I have been developing my first User login & authentication system using Passport.js. 在过去的几天里,我一直在使用Passport.js开发我的第一个用户登录和身份验证系统。 Awkwardly enough, I have finished it and it works just as intended. 很尴尬,我已经完成了它,它的工作原理与预期一致。 The problem is, even though I have read a lot of articles and checked tens of examples online, I seem to not completely understand the code per se. 问题是,即使我已经阅读了大量文章并在线检查了数十个例子,我似乎并不完全理解代码本身。 I have no issues understanding the process behind it and why it has to happen like that. 我没有理解它背后的过程以及它为什么会这样发生的问题。 I would really appreciate it if you could clarify some parts of the code for me. 如果你能为我澄清代码的某些部分,我将非常感激。 This is the working code, stored in my app.js file: 这是工作代码,存储在我的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')));

});

I am using MongoDB (User - mongoose model). 我正在使用MongoDB(用户 - 猫鼬模型)。 Also, to store passwords in the database I am currently using bcrypt. 另外,要在我正在使用bcrypt的数据库中存储密码。

I think that the most critical part that I do not understand here is the done callback function. 我认为这里我不了解的最关键部分是完成回调函数。 I can understand that it simply passes some values, and I know that much to realize that the first parameter of it is the error and the second the data. 我可以理解它只是传递了一些值,我知道很多东西要意识到它的第一个参数是错误,第二个参数是数据。 Still, I do not fully grasp it because I haven't specifically provided one as a parameter. 不过,我还没有完全掌握它,因为我没有特别提供一个作为参数。 For example, if I would have a function like this: 例如,如果我有这样的函数:

// 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; });

Still, in my example I am not the one specifying the done callback. 不过,在我的例子中,我不是指定完成回调的那个。 Is it simply a required callback function parameter or is it the same as the next function in a normal middleware such as: 它只是一个必需的回调函数参数,还是与普通中间件中的下一个函数相同,例如:

function middleware (req, res, next) {
    next(req.user); // pass the req.user to next middleware
}

Also, where does Passport.js bind the user that it handles? 另外,Passport.js绑定它处理的用户在哪里? Does it bind it to req.user ? 它是否将它绑定到req.user And how can I pass it to certain views in order, for example, to display the username? 我怎样才能将它传递给某些视图,例如显示用户名?

I am looking forward to your feedback! 我期待着您的反馈!

Thank you! 谢谢!

Done callback 完成回调

Look at the code of Local Strategy : 看看本地策略的代码:

function Strategy(options, verify) {
  ...
  this._verify = verify;
  ...
}

verify is the function that will be used by strategy to verify a user and you've specified it here: verify是策略用于验证用户的功能,您在此处指定了它:

passport.use(new LocalStrategy(function (username, password, done) {
    // your verification code here
}));

Later in strategy you can find authenticate method that calls verify function from the step above: 稍后在策略中,您可以找到从上面的步骤调用验证函数的authenticate方法:

this._verify(username, password, verified);

So, you now see where username , password and done==verified come from. 所以,你现在看到usernamepassworddone==verified来自哪里。 Later in your code you will call the done callback with (err, user, info) arguments. 稍后在代码中,您将使用(错误,用户,信息)参数调用done回调。 In a few words, done is needed to finish asynchronous procedure of user verification. 在几句话, done需要完成用户验证的异步过程。

req.user and views req.user和views

Yes, you are right about req.user . 是的,你对req.user是正确的。 So you can pass it to your views by two ways: 所以你可以通过两种方式将它传递给你的观点:

  1. As an argument of res.render function. 作为res.render函数的参数。 See docs 查看文档

     res.render('some-template', { name: req.user }); 
  2. Use res.locals as some kind of context provider (now user object will be available in all the views that are defined in app.router ). 使用res.locals作为某种上下文提供程序(现在用户对象将在app.router中定义的所有视图中app.router )。 See docs 查看文档

     // before app.use(app.router); app.use(function(req, res, next) { res.locals.user = req.user; next(); }); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM