介绍Passport.js (Introducing Passport.js)
Passport.js is an authentication middleware. It attempts to implement local authentication of users and make logging in/logging out simpler.It is flexible in the sense that it allows for different authentication strategies (think via Twitter, via our own user database — installed via separate modules that can be combined) and it allows us to specify any route or output during authentication.
Passport.js是身份验证中间件。 它尝试实现对用户的本地身份验证,并使登录/注销更加简单。从某种意义上说,它可以灵活地实现不同的身份验证策略(例如通过Twitter,通过我们自己的用户数据库(通过可以组合的单独模块安装)进行思考)它允许我们在身份验证期间指定任何路由或输出。
The Local Strategy allows us to authenticate users by looking up their data in the app’s database.
本地策略允许我们通过在应用程序数据库中查找用户的数据来对用户进行身份验证。
Let’s see how can we integrate it.
让我们看看如何集成它。
To get started, let us first create a basic express app using the following command.
首先,让我们首先使用以下命令创建一个基本的Express应用程序。
npx express-generator
Next, we will install a few modules that we will need.
接下来,我们将安装一些我们需要的模块。
npm install body-parser express-session passport passport-local bcryptjs mongoose
Now, you might be familiar with body-parser,express-session and mongoose.passport is the npm module that helps us use Passport.js, passport-local will help us define a ‘local strategy’ (more on that later) and bcryptjs is used to safely hash and store our user’s passwords.
现在,您可能已经熟悉了body-parser,express-session和mongoose 。 护照是帮助我们使用Passport.js的npm模块, passport-local将帮助我们定义“本地策略”(稍后会详细介绍),而bcryptjs用于安全地哈希和存储用户密码。
Let’s add these modules to our app.js file.
让我们将这些模块添加到我们的app.js文件中。
var bodyParser = require('body-parser');
var session = require('express-session');
var passport = require('passport');
var mongoose = require('mongoose');
var LocalStrategy = require('passport-local');
var mongoose = require('mongoose');app.use(session({
secret: 'secret',
saveUninitialized: true,
resave: true
}));app.use(passport.initialize());
app.use(passport.session());app.use(bodyParsor.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use(cookieParser());passport.serializeUser(function(user,done){
done(null,user.id);
});passport.deserializeUser(function(id,done){
User.findById(id, function(err,user){
done(err,user);
})
})var mongoURI = YOUR_MONGO_URI;
mongoose.connect(mongoURI, {
useUnifiedTopology: true,
useNewUrlParser: true,
})
.then(() => console.log('DB Connected!'))
.catch(err => {
console.log(err);
});var conn = mongoose.connection;
Make sure you do not mess up the order of the variables. It is really important you follow the order.
确保不弄乱变量的顺序。 遵循顺序非常重要。
Now the fun part!Before we go ahead and setup passport, let’s take a look at the user model.
现在有趣的部分!在继续设置护照之前,让我们看一下用户模型。
var mongoose = require("mongoose");var bcrypt = require("bcryptjs");var userSchema = mongoose.Schema({
name: String,
email: String,
username: String,
password: String
});var User = module.exports = mongoose.model("User", userSchema);
So as you can see, we have setup a basic user model. Now we need to hash our password values. To do this, we take the help of bcrypt. As you can guess by the name, bcrypt is a library that hashes the password and stores it. We can implement this in our user model now.
如您所见,我们已经建立了基本的用户模型。 现在我们需要哈希密码值。 为此,我们借助bcrypt。 正如您所猜测的那样,bcrypt是一个散列并存储密码的库。 现在,我们可以在用户模型中实现此功能。
module.exports.createUser = function(newUser, callback) {
bcrypt.genSalt(5,function(err,salt){
bcrypt.hash(newUser.password,salt,function(err,hash){
newUser.password = hash;
newUser.save(callback);
});
});
}
Now, we need to add a few more methods in the users model.comparePassword compares two passwords, one that is a hashed value, and determines if it is the same.getUserByUsername returns a user with the specified username.
现在,我们需要在用户模型中添加更多方法.comparePassword比较两个密码,一个是散列值,然后确定是否相同。 getUserByUsername返回具有指定用户名的用户。
module.exports.comparePassword = function(candidatePassword, hash, callback){
bcrypt.compare(candidatePassword, hash, function(err, isMatch) {
callback(err, isMatch);
});
}module.exports.getUserByUsername = function(username, callback){
var query = {username: username};
User.findOne(query, callback);
}
So now we define the Local Strategy. What a local strategy is, is basically a way to specify how to authenticate users.
因此,现在我们定义本地策略。 本地策略基本上是一种指定如何验证用户身份的方法。
You have a user trying to login. What do you do?You first check if the user is already registered in your database. If they haven’t registered yet, then you throw an error. If they are, they you check if the password specified by the user is the same as the password registered in the database. This is exactly what we wish to accomplish in the following lines of code. Now, let’s define the local strategy in the app.js file.
您有一个试图登录的用户。 您做什么?首先检查用户是否已经在数据库中注册。 如果尚未注册,则会引发错误。 如果是,请检查用户指定的密码是否与数据库中注册的密码相同。 这正是我们希望在以下代码行中完成的工作。 现在,让我们在app.js文件中定义本地策略。
passport.use(new LocalStrategy(
function(username, password, done) {
User.findOne({username:username}, function(err, user){
if(err) throw err;
if(!user)
done(null,false, {message: 'Unknown user'});
User.comparePassword(password,user.password,function(err, isMatch){
if(err)
done(err);
if(isMatch)
done(null,user);
else
done(null, false, {message: 'Invalid password'});
});
});
}
));
All that’s left to do now is add the routes and a simple view page to test out our app.
现在要做的就是添加路线和一个简单的查看页面,以测试我们的应用程序。
var express = require('express');
var router = express.Router();
var passport = require("passport");
var User = require('../models/users');
/* GET users listing. */
router.get("/login", function(req,res){
console.log(req.user);
res.render("user/login.ejs");
});
router.post("/login", passport.authenticate('local',{successRedirect: '/',
failureRedirect: '/user/login'}), function (req, res) {});
router.get("/signup", function(req,res){
res.render("user/signup.ejs");
});
router.post("/signup", function (req, res) {
console.log(req.body);
var password = req.body.password;
var password2 = req.body.password2;
if(password == password2) {
var newUser = new User ({
name: req.body.name,
email: req.body.email,
username: req.body.username,
password: req.body.username
});
User.createUser(newUser, function(err, user){
if(err)
throw err;
console.log(user);
res.send(user).end();
});
} else {
res.status(500).send("{errors: \"Passwords don't match\"}").end()
}
});
router.get("/logout", function (req, res) {
req.logout();
res.redirect("/");
});
module.exports = router;
login.ejs
login.ejs
<div class="container" id="login">
<div class="right">
<h1>LOGIN</h1>
<div id="form">
<form action="/users/login" method="POST">
<div class="form-group">
<input type="text" name="username" id="username" placeholder="Username">
</div>
<div class="form-group">
<input type="password" name="password" id="password" placeholder="Password">
</div>
<button class="btn btn-dark" type="submit" class="submit-btn">-></button>
</form>
</div>
<span class="text-right">Don't have an account? <a href="/users/signup">Sign Up.</a></span>
</div>
</div>
signup.ejs
signup.ejs
<div class = "container" id = "signup">
<div class="right">
<h1>SIGN UP</h1>
<div id = "form" >
<form action="/users/signup" method = "POST">
<div class = "form-group">
<input type = "text" name = "name" id = "name" placeholder="Name">
</div>
<div class="form-group">
<input type = "text" name = "email" id = "email" placeholder="E-mail">
</div>
<div class="form-group">
<input type = "text" name = "username" id = "username" placeholder="Username">
</div>
<div class="form-group">
<input type="password" name="password" id="password" placeholder="Password">
</div>
<div class="form-group">
<input type="password" name="password2" id="password2" placeholder="Re-enter Password">
</div>
<button class = "btn btn-dark" type = "submit" class = "submit-btn">Create Account</button>
</form>
</div>
<span class="text-right">Already have an account? <a href="/users/login">Sign In.</a></span>
</div>
</div>
Now, run the app and try to sign up and sign in!
现在,运行该应用程序并尝试注册并登录!
Here’s the Github repository for the code : https://github.com/aishwarya-29/development/tree/master/User%20authentication%20using%20Passport
这是代码的Github存储库: https : //github.com/aishwarya-29/development/tree/master/User%20authentication%20using%20Passport
Happy Coding :)
快乐编码:)
翻译自: https://medium.com/@aishwaryababu1212/user-authentication-with-passport-js-720eddb56cfc