欢迎访问宙启技术站
智能推送

node.js+captchapng+jsonwebtoken实现登录验证示例

发布时间:2023-05-16 07:48:10

本文将介绍如何结合node.js中的captchapng和jsonwebtoken实现登录验证功能。captchapng用于生成验证码图片,jsonwebtoken用于生成和验证访问令牌。通过将这两个库结合在一起,我们可以实现一个安全、可靠的登录验证流程。

首先,我们需要安装captchapng和jsonwebtoken模块。在命令行中输入以下命令:

npm install captchapng jsonwebtoken

接下来,我们创建一个server.js文件。这个文件将作为我们的Web应用的主文件,负责接受用户的请求,并处理登录验证过程。以下是这个文件的具体代码:

const express = require("express");
const bodyParser = require("body-parser");
const captchapng = require("captchapng");
const jwt = require("jsonwebtoken");

const app = express();

app.use(bodyParser.json()); // 解析 json 请求体
app.use(bodyParser.urlencoded({ extended: true })); // 解析 urlencoded 请求体

// 生成验证码图片
app.get("/captcha", function (req, res) {
  const randomNumber = parseInt(Math.random() * 9000 + 1000); // 生成随机四位数
  const png = new captchapng(80, 30, randomNumber); // 生成图片
  const pngData = png.getBuffer();
  const base64Data = pngData.toString("base64"); // 转成 base64 格式
  const imgBuffer = new Buffer.from(base64Data, "base64"); // 转成 Buffer 格式
  res.writeHead(200, {
    "Content-Type": "image/png",
  });
  res.end(imgBuffer);
});

// 处理登录请求
app.post("/login", function (req, res) {
  const { username, password, captchaCode } = req.body;
  // 验证码验证
  if (captchaCode !== req.session.captcha) {
    res.json({ status: "failed", message: "验证码错误" });
    return;
  }
  // 用户名密码验证
  if (username === "admin" && password === "123456") {
    const token = jwt.sign({ username: "admin" }, "secret", {
      expiresIn: 1800, // 单位为秒,过期时间为 30 分钟
    });
    res.json({ status: "success", token });
  } else {
    res.json({ status: "failed", message: "用户名或密码错误" });
  }
});

app.listen(3000, () => {
  console.log("Server is running on port 3000");
});

上述代码中,我们首先引入了必要的模块,然后创建了一个Express应用程序。body-parser中间件用于解析请求体,captchapng用于生成验证码图片,jsonwebtoken用于生成和验证访问令牌。

接下来,我们定义了两个路由:/captcha/login/captcha用于生成验证码图片,/login用于处理登录请求。在/captcha路由中,我们首先生成一个四位数的随机数,然后使用captchapng库生成一个80像素宽、30像素高的验证码图片。最后,将生成的图片发送给客户端。

/login路由中,我们从请求体中解析出用户名、密码和验证码。先验证验证码是否正确,如果不正确,则返回错误响应。如果验证码正确,则继续验证用户名和密码。这里我只是简单地判断输入的用户名和密码是否为"admin"和"123456",实际应用中需要根据业务逻辑进行验证。

如果用户名和密码正确,则使用jsonwebtoken库生成一个访问令牌,然后将它作为响应发送给客户端。如果用户名和密码不正确,则返回错误响应。

让我们来看看如何创建和验证访问令牌。在上面的/login路由中,我们使用以下代码创建访问令牌:

const token = jwt.sign({ username: "admin" }, "secret", {
  expiresIn: 1800, // 单位为秒,过期时间为 30 分钟
});

这里,我们调用jwt.sign方法,传入一个对象,该对象包含一个username字段,用于指定令牌所属的用户。第二个参数是一个字符串,用于指定用于加密令牌的密钥。第三个参数是一个选项对象,用于指定令牌的过期时间。在上面的代码中,我们将过期时间设置为30分钟。

当我们要验证传入的访问令牌时,需要使用以下代码:

const token = req.headers.authorization.split(" ")[1];
jwt.verify(token, "secret", (err, decoded) => {
  if (err) {
    res.json({ status: "failed", message: "无效的令牌" });
    return;
  }
  req.user = decoded; // 将解码后的用户信息存储在请求对象中
  next(); // 继续处理请求
});

这里,我们首先从请求头中获取访问令牌,并把它传给jwt.verify方法进行验证。如果令牌无效,则返回错误响应。否则,我们将解码后的用户信息存储在请求对象中,并调用next函数继续处理请求。

到这里,我们已经实现了一个基本的登录验证流程。用户调用/captcha路由获取验证码图片。当用户想要登录时,他必须通过POST请求发送他的用户名、密码和验证码。服务器验证这些信息,如果它们都正确,则返回一个包含访问令牌的响应。用户在以后的请求中可以在请求头中发送自己的访问令牌以进行身份验证。