在 Node.js 中解释 Passport?
Passport 是一个 Node 包或库,我们可以将其安装到任何 Node.js 项目中。Passport 提供了应用程序身份验证的功能。此外,它还提供不同的加密策略来加密用户信息,例如密码。
例如,如果 Facebook 或 Google 的员工能够看到其用户的密码会怎样?这违反了用户隐私。因此,在这种情况下,我们可以使用 Passport,它会加密密码并将其存储在数据库中。我们需要知道解密算法和密钥才能解密密码。
此外,Passport 允许我们为用户建立身份验证会话。假设您每次关闭浏览器时都必须重新登录。这很耗时。不是吗?因此,Passport 允许我们通过在浏览器中存储 Cookie 来为特定时间建立会话。在开发人员设置的特定会话时间内,用户每次访问网页时都不需要登录。
在这里,我们将创建一个基本的身份验证应用程序并学习如何在 Node.js 中使用 Passport。
创建应用程序的步骤
步骤 1 - 创建您想要开始新 Node.js 项目的文件夹。
步骤 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 是 Node.js 的 Web 框架。它允许用户用更少的代码行创建 Node.js 应用程序服务器。
body-parser 用于从用户那里获取表单输入数据。Mongoose 允许我们使用 MongoDB 数据库。
Passport NPM 包用于在我们的应用程序中使用 Passport。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 表单获取用户的电子邮件和密码。我们为电子邮件和密码创建了两个不同的输入字段。此外,我们创建了提交按钮,当用户按下它时,应用程序将在“/register 路由上发出 POST 请求。
步骤 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”路由上发出 POST 请求。
步骤 6 - 现在,我们将开始创建我们的服务器。我们将导入所需的模块并使用 Passport 初始化我们的应用程序。
// 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:[email protected]/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 模式来存储用户的身份验证数据。接下来,我们将用户模式与 passportLocalMongoose 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 - 我们必须处理“/register”路由上的 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!"); } } ); }); } } ); });
在上面的代码中,我们从用户那里获取登录凭据。我们从数据库中查找用户并使用 Passport 对其进行身份验证。在没有错误的情况下进行身份验证后,我们发送一条类似“用户登录成功!”的消息。
步骤 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:[email protected]/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