解释一下Node.js中的Passport
Passport是一个节点包,或库,我们可以在任何nodeJs项目中安装。Passport提供了应用程序中的认证功能。此外,它还提供了不同的加密策略来加密用户信息,如密码。
例如,如果Facebook或谷歌的员工可以看到他们用户的密码呢?这是对用户隐私的侵犯。因此,在这种情况下,我们可以使用Passport,它对密码进行加密并存储在数据库中。我们应该知道解密算法和秘密密钥来解密密码。
另外,Passport允许我们为用户建立认证会话。假设你每次关闭浏览器都必须再次登录。这很耗费时间。不是吗?因此,Passport允许我们通过在浏览器中存储cookies来建立一个特定时间的会话。只要用户在开发者设定的特定会话时间内访问网页,就不需要登录。
在这里,我们将创建一个基本的认证应用程序,并学习Passport与NodeJs的使用。
创建应用程序的步骤
第1步 – 创建你想启动新NodeJs项目的文件夹。
第2步 – 输入下面的命令来启动一个新的Node项目。它将在项目文件夹中创建一个名为package.json的文件。
npm init -y
第3步 – 用户必须为他们的node项目安装所需的插件。打开终端,进入项目目录,并输入下面的命令来安装所有的NPM包。
npm install express body-parser mongoose passport passport-local
passport-local-mongoose express-session
在上述命令中,Express是NodeJs的一个网络框架。它允许用户用较少的代码行创建nodeJs应用服务器。
body-parser用于从用户那里获取表单输入数据。Mongoose允许我们使用MongoDB数据库。
passport NPM包用于我们应用程序中的护照。Passport-local包含大约450种策略来加密数据。passport-local-mongoose使用MongoDB与Passport和express-session来维护使用Passport和express的登录会话。
第4步 – 现在,让我们创建一个表格来注册用户。在项目目录下创建register.html文件并粘贴下面的代码。
示例
<html>
<body>
<h2>
Enter email and password values, and press submit button for registration
</h2>
<!-- Make the post request on the /register route with email and password data -->
<form action = "/register" method = "post">
<input type = "email" name = "username" />
<br />
<input type = "password" name = "password" />
<br />
<button type = "submit" name = "button"> Submit </button>
</form>
</body>
</html>
在上面的代码中,我们已经创建了一个使用HTML表格获取用户的电子邮件和密码的表格。我们为电子邮件和密码创建了两个不同的输入字段。此外,我们还创建了提交按钮,当用户按下该按钮时,应用程序将在”/注册路线 “上进行发布请求。
第5步 – 现在,让我们来创建登录页面的代码。在项目目录下创建login.html文件并粘贴以下代码。
示例
<html>
<body>
<h2> Enter the credentials to log in to the app</h2>
<!-- When the user presses the submit button, it makes a post request on the login route -->
<form action = "/login" method = "post">
<input type = "email" name = "username" />
<br />
<input type = "password" name = "password" />
<br />
<button type = "submit" name = "button"> Submit </button>
</form>
</body>
</html>
上面的代码与我们在register.html中写的几乎一样,但不同的是,当用户按下提交按钮时,它在’/login’路线上发出了帖子请求。
第6步 – 现在,我们将开始创建我们的服务器。我们将导入所需的模块,并用护照来初始化我们的应用程序。
// Importing the required and installed modules
var express = require("express");
var app = express();
const mongoose = require("mongoose");
const bodyParser = require("body-parser");
const session = require("express-session");
const passport = require("passport");
const passportLocalMongoose = require("passport-local-mongoose");
// permitting the app to use body-parser without any error
app.use(bodyParser.urlencoded({ extended: true }));
app.use(
session({
secret: "This is the secret key to encrypt the password and user data.",
resave: false,
saveUninitialized: false,
})
);
// initialize our app with passport and establish a session
app.use(passport.initialize());
app.use(passport.session());
在上面的代码中,我们已经导入了模块并使用Passport初始化了我们的应用程序。此外,我们还使用Passport建立了会话。
第7步 – 我们需要将MongoDB数据库与我们的应用程序连接起来。
mongoose
.connect(
"mongodb+srv://shubhamvora05:Stockdata@stockdata.lrlgm.mongodb.net/StockList?retryWrites=true&w=majority",
{ useNewUrlParser: true, useUnifiedTopology: true }
)
.then(() => {
console.log("Connected to database successfully");
})
.catch((err) => {
console.log("Error connecting to MongoDB database", err.message);
});
// creating the user schema containing the email_Adress and password field
const user = new mongoose.Schema({
email_Address: String,
password: String,
});
// code to use the Mongoose schema named user with passport
user.plugin(passportLocalMongoose);
// Creating the new model using the schema
const userModel = new mongoose.model("User", user);
// create the strategy to encrypt the data
passport.use(userModel.createStrategy());
passport.serializeUser(userModel.serializeUser());
passport.deserializeUser(userModel.deserializeUser());
在上面的代码中,我们首先将我们的应用程序与MongoDB集群相连。之后,我们创建了名为user的MongoDB模式来存储用户的认证数据。接下来,我们用passortLocalMongoose NPM包对用户模式进行了插件。此外,我们在上面的代码中使用了序列化器和反序列化器。
第8步 – 我们需要处理来自主页和登录路线的GET请求。
app.get("/", function (req, res) {
if (req.isAuthenticated()) {
res.send("Authenticated successfully");
} else {
res.sendFile(__dirname + "/register.html");
}
});
app.get("/login", function (req, res) {
if (req.isAuthenticated()) {
res.send("Authenticated successfully");
} else {
res.sendFile(__dirname + "/login.html");
}
});
在上面的代码中,isAuthenticated()是中间件函数,用于检查用户是否已经登录并发送布尔值。
第9步 – 我们必须在’/注册’路线上处理POST请求。
app.post("/register", function (req, res) {
userModel.register(
{ username: req.body.username },
req.body.password,
function (err, user) {
if (!err) {
passport.authenticate("local")(req, res, function () {
res.send("User registered successfully with email!");
});
}
}
);
});
在上面的代码中,我们使用passport.authenticate()方法对密码进行了加密并存储在数据库中。
第10步 – 接下来,我们需要处理’/login’路线的POST请求。
app.post("/login", function (req, res) {
req.login(
{
username: req.body.username,
password: req.body.password,
},
function (err) {
if (!err) {
passport.authenticate("local")(req, res, function () {
userModel.find(
{ email_Address: req.user.username },
(err) => {
if (!err) {
res.send("User login successful! Enjoy Now!");
}
}
);
});
}
}
);
});
在上面的代码中,我们从用户那里获得登录凭证。我们从数据库中找到用户并使用护照对其进行认证。在没有错误的情况下,我们发送一个消息,如 “用户登录成功!”的认证。
第11步 – 创建server.js文件并粘贴以下代码。
// Importing the required and installed modules
var express = require("express");
var app = express();
const mongoose = require("mongoose");
const bodyParser = require("body-parser");
const session = require("express-session");
const passport = require("passport");
const passportLocalMongoose = require("passport-local-mongoose");
// give permission to the app to use body-parser without any error
app.use(bodyParser.urlencoded({ extended: true }));
app.use(
session({
secret: "This is the secrect key to encrypt the password and user data.",
resave: false,
saveUninitialized: false,
})
);
// initialize our app with passport and establish a session
app.use(passport.initialize());
app.use(passport.session());
// Connecting MongoDB cluster to our app using the mongoose NPM package
mongoose
.connect(
"mongodb+srv://shubhamvora05:Stockdata@stockdata.lrlgm.mongodb.net/StockList?retryWrites=true&w=majority",
{ useNewUrlParser: true, useUnifiedTopology: true }
)
.then(() => {
console.log("Connected to database successfully");
})
.catch((err) => {
console.log("Error connecting to MongoDB database", err.message);
});
// creating the user schema containing the email_Adress and password field
const user = new mongoose.Schema({
email_Address: String,
password: String,
});
// code to use the Mongoose schema named user with passport
user.plugin(passportLocalMongoose);
// Creating the new model using the schema
const userModel = new mongoose.model("User", user);
// create the stratagy to encry the data
passport.use(userModel.createStrategy());
passport.serializeUser(userModel.serializeUser());
passport.deserializeUser(userModel.deserializeUser());
// handling the get request
// if user is authenticated then send response message "Authenticated successfullly"
// Othewise redirect user to register page.
app.get("/", function (req, res) {
if (req.isAuthenticated()) {
res.send("Authenticated successfully");
} else {
res.sendFile(__dirname + "/register.html");
}
});
// Same like the register route,
// If user is authenticated then send response, othewise redirect to login route
app.get("/login", function (req, res) {
if (req.isAuthenticated()) {
res.send("Authenticated successfully");
} else {
res.sendFile(__dirname + "/login.html");
}
});
/* Registering the user for the first time
handling the post request on /register route.*/
app.post("/register", function (req, res) {
userModel.register(
{ username: req.body.username },
req.body.password,
function (err, user) {
// registering using the passport
if (!err) {
passport.authenticate("local")(req, res, function () {
res.send("User registered successfully with email!");
});
}
}
);
});
// Handling the post request on /login route
app.post("/login", function (req, res) {
// requesting the login using passport
req.login(
{
username: req.body.username,
password: req.body.password,
},
function (err) {
if (!err) {
// authenticating using passport
passport.authenticate("local")(req, res, function () {
userModel.find(
{ email_Address: req.user.username },
function (err, docs) {
if (!err) {
res.send("User login successful! Enjoy Now!");
}
}
);
});
}
}
);
});
// Allowing the app to listen on port 3000
app.listen(3000, function () {
console.log("server started successfully");
});
第12步 – 作为最后一步,我们需要运行我们的应用程序。要运行该应用程序,在终端输入以下命令。
node server.js