在 Node.js 中使用 Passport 进行本地身份验证

10,218次阅读
没有评论

共计 4800 个字符,预计需要花费 12 分钟才能阅读完成。

一、简介

Passport.js 是专为 Nodejs 设计的身份验证中间件。passport-local 使用通行证策略通过用户名和密码进行身份验证。该模块有助于在 nodejs 应用程序中使用用户名和密码进行身份验证。

1.1 设置 Node.js

要建立的 Node.js 在 Windows 上,您将需要前往 Node 官网下载 。选择适用于您平台的安装程序(还包括 NPM 包管理器)并运行安装程序以启动 Node.js 安装向导。按照向导步骤操作,完成后单击“完成”。如果一切顺利,您可以导航到命令提示符以验证安装是否成功,如图 1 所示。

Node.js 中的 Passport - npm 安装
图 1:验证节点和 npm 安装

2. 在 Node.js 中使用 Passport 进行本地身份验证

要设置应用程序,我们需要导航到项目所在的路径。对于编程,我使用​Visual Studio Code​作为我的首选 IDE。您可以自由选择自己喜欢的 IDE。

2.1 设置实现

让我们编写实际学习所需的不同文件。

2.1.1 设置依赖

导航到项目目录并运行 npm init - y 以创建 package.json 文件。该文件包含与项目相关的元数据,用于管理项目依赖项、脚本、版本等。将以下代码添加到文件中,我们将在其中指定所需的依赖项。

{
  "name": "passport-app",
  "version": "1.0.0",
  "description": "","main":"server.js","scripts": {"start":"nodemon server.js"},"keywords": [],"author":"",
  "license": "ISC",
  "dependencies": {
    "bcrypt": "^5.0.1",
    "ejs": "^3.1.6",
    "express": "^4.17.1",
    "express-flash": "0.0.2",
    "express-session": "^1.17.2",
    "method-override": "^3.0.0",
    "passport": "^0.4.1",
    "passport-local": "^1.0.0"
  },
  "devDependencies": {
    "dotenv": "^10.0.0",
    "nodemon": "^2.0.12"
  }
}

要下载依赖项,请导航到包含该文件的目录路径并使用 npm install​命令。如果一切顺利,依赖项将加载到​node_modules​文件夹中,您可以继续执行进一步的步骤。

2.1.2 视图 – 创建欢迎屏幕

在根文件夹中创建一个名为​views​的文件夹并将以下内容添加到​index.ejs​. 此屏幕将负责在成功验证后显示欢迎页面。

Hi

2.1.3 查看——创建登录界面

在根文件夹中创建一个名为​views​的文件夹并将以下内容添加到​login.ejs​. 此屏幕将负责登录。

Login

Sign up

2.1.4 视图 – 创建注册屏幕

在根文件夹中创建一个名为​views​的文件夹并将以下内容添加到​login.ejs​. 此屏幕将负责新用户的注册。

Register

Login

2.1.5 创建通行证配置

在根文件夹中,将以下内容添加到配置文件中。该文件将负责使用用户名和密码配置策略。该策略还需要一个回调,该回调将接受凭据并调用一个​done(…)​方法来提供用户详细信息。

// adding passport related configuration
 
const LocalStrategy = require("passport-local").Strategy;
const bcrypt = require("bcrypt");
 
function initialize(passport, getUserByEmail, getUserById) {const authenticateUser = async (email, password, done) => {const user = getUserByEmail(email);
    if (user == null) {return done(null, false, { message: "User not found"});
    }
 
    try {if (await bcrypt.compare(password, user.password)) {return done(null, user);
      } else {return done(null, false, { message: "Invalid credentials"});
      }
    } catch (e) {return done(e);
    }
  };
 
  passport.use(new LocalStrategy({ usernameField: "email"}, authenticateUser));
  passport.serializeUser((user, done) => done(null, user.id));
  passport.deserializeUser((id, done) => {return done(null, getUserById(id));
  });
}
 
module.exports = initialize;

2.1.6 创建控制器

在根文件夹中,将以下内容添加到索引文件中。该文件将负责初始化导入、路由并指定通行证配置以验证请求。请记住​.env​在同一位置创建一个文件并指定敏感信息,例如会话机密、应用程序端口号等。

if (process.env.NODE_ENV !== "production") {require("dotenv").config();}
 
// imports
const express = require("express");
const app = express();
const bcrypt = require("bcrypt");
const passport = require("passport");
const flash = require("express-flash");
const session = require("express-session");
const methodOverride = require("method-override");
 
// todo - add external db support
const users = [];
 
// configuring and initializing passport
const initializePassport = require("./passport-config");
initializePassport(
  passport,
  (email) => users.find((user) => user.email === email),
  (id) => users.find((user) => user.id === id)
);
 
app.set("view-engine", "ejs");
app.use(express.urlencoded({ extended: false}));
app.use(flash());
app.use(
  session({
    secret: process.env.SESSION_SECRET || "8unto0n4oc7903zm",
    resave: false,
    saveUninitialized: false,
  })
);
app.use(passport.initialize());
app.use(passport.session());
app.use(methodOverride("_method"));
 
// routes
 
// welcome page
// display greetings message for the user and logout button
app.get("/", checkAuthenticated, (req, res) => {res.render("index.ejs", { name: req.user.name});
});
 
// login page
app.get("/login", checkNotAuthenticated, (req, res) => {res.render("login.ejs");
});
 
app.post(
  "/login",
  checkNotAuthenticated,
  passport.authenticate("local", {
    successRedirect: "/",
    failureRedirect: "/login",
    failureFlash: true,
  })
);
 
// new user sign-up page
app.get("/register", checkNotAuthenticated, (req, res) => {res.render("register.ejs");
});
 
app.post("/register", checkNotAuthenticated, async (req, res) => {
  try {const hashedPassword = await bcrypt.hash(req.body.password, 10);
    users.push({id: "_" + Math.random().toString(36).slice(2),
      name: req.body.name,
      email: req.body.email,
      password: hashedPassword,
    });
 
    res.redirect("/login");
  } catch (e) {// console.log(e);
    res.redirect("/redirect");
  }
 
  // check if the user is successfully added to array
  // console.log(users);
});
 
// logout of the application
app.delete("/logout", (req, res) => {req.logOut();
  res.redirect("/login");
});
 
// util methods
 
// only authenticated user should enter index page
function checkAuthenticated(req, res, next) {if (req.isAuthenticated()) {return next();
  } else {res.redirect("/login");
  }
}
 
// unauthenticated user should not enter index page
function checkNotAuthenticated(req, res, next) {if (req.isAuthenticated()) {return res.redirect("/");
  }
  next();}
 
// start server
const port = process.env.APPLICATION_PORT || 6001;
app.listen(port, () => {console.log("Server listening at http://localhost:%s", port);
});

3. 运行应用程序

要运行应用程序,请导航到项目目录并输入以下命令,如图 2 所示。如果一切顺利,应用程序将在从​.env​文件或 6001.

Node.js 中的 Passport - 启动应用程序
图 2:启动应用程序

4. 演示

应用程序成功启动后,导航到以下 url 以显示登录屏幕。您可以单击注册按钮以创建新用户并在此之后使用该应用程序。

http://localhost:YOUR_PORT_NUMBER

这就是本教程的全部内容,我希望这篇文章能够为您提供所需的一切。快乐学习,不要忘记分享!

5. 总结

在本篇文章中,我们了解了 passport 模块以及如何在 passport-local 依赖项的帮助下创建一个简单的登录应用程序。

原文地址: 在 Node.js 中使用 Passport 进行本地身份验证

    正文完
     0
    Yojack
    版权声明:本篇文章由 Yojack 于2024-09-23发表,共计4800字。
    转载说明:
    1 本网站名称:优杰开发笔记
    2 本站永久网址:https://yojack.cn
    3 本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长进行删除处理。
    4 本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
    5 本站所有内容均可转载及分享, 但请注明出处
    6 我们始终尊重原创作者的版权,所有文章在发布时,均尽可能注明出处与作者。
    7 站长邮箱:laylwenl@gmail.com
    评论(没有评论)