如何在Express.js应用中实现JWT身份验证

如何在Express.js应用中实现JWT身份验证

JSON Web Token

JSON Web Token(JWT)是一种JSON对象,用于在网络上安全地传输信息(在两个实体之间)。它通常用于身份验证系统,并且还可以用于信息交换。

它用于在互联网上加密传输数据,这些令牌可以通过使用附加签名更加安全。这些令牌由头部JSON、有效负载JSON以及可选签名组成;每个都使用“.”连接。

下面是JSON Web Token的示例。

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI2MTU0OWIwMTIwMWUyZjMzZWE3NmFkZjYiLCJlbWFpbCI6InNtdHdpbmtsZTQ1MkBnbWFpbC5jb20iLCJpYXQiOjE2MzI5MzQ2NTgsImV4cCI6MTYzMjkzODI1OH0._oHr3REme2pjDDdRliArAeVG_HuimbdM5suTw8HI7uc

JWT身份验证的实现: JWT在使用HTTP进行身份验证和授权方面非常流行。这些令牌可以用作授予访问服务器资源的凭据。

为什么我们在身份验证中需要JWT: 由于HTTP请求是无状态的,要知道当前请求与之前的请求是否相关是一项具有挑战性的任务。例如,登录后,用户具有更改其数据的权利,但在下一次请求时,服务器如何识别这是之前请求登录的同一用户。为解决这个挑战,我们使用JWT。

在第一步中,服务器使用某些配置(如有效负载、签名、过期等)生成一个令牌。下一次,当来自客户端的请求到达时,授权头部包含JWT令牌,服务器解码该令牌并使用详细信息,然后根据情况允许访问。

如何在Express.js应用中实现JWT身份验证

示例:- 让我们创建一个简单的服务器,它具有登录和注册功能。

步骤1:初始化服务器并安装JWT包。

npm init
npm install **jsonwebtoken**

步骤2:创建令牌路由

解释:

  • 我们在第一行中导入了express、mongoose和jsonwebtoken,并且还导入了User模型,因为这在与数据库交互时是必要的。在下一行中,我们调用了express方法,该方法返回一个app对象,我们可以用它来配置我们的服务器。我们在开始时使用express.json中间件,以便服务器可以将传入的请求识别为JSON对象。
  • 随后,我们创建了两个路由,一个用于登录,另一个用于注册。
  • 在登录路由内部,我们从请求体中提取了电子邮件和密码,然后在数据库中搜索该用户,如果找到了该用户,则继续检查提供的密码是否与实际密码匹配。
  • 在注册路由内部,我们提取了姓名、电子邮件和密码等详细信息,以便在数据库中注册用户,并使用mongoose提供的save方法。

最后,我们通过提供用户ID和电子邮件作为有效载荷,创建了一个有效期为1小时的 令牌 ,因为只有这些信息足以提取用户信息。sign方法接受有效载荷、秘密jwt密钥和过期时间,然后生成一个令牌。

文件名:app.js

// Importing modules
const express = require("express");
const mongoose = require("mongoose");
 
const jwt = require("jsonwebtoken");
const User = require("./userModel");
 
const app = express();
 
app.use(express.json());
 
// Handling post request
app.post("/login", async (req, res, next) => {
  let { email, password } = req.body;
 
  let existingUser;
  try {
    existingUser = await User.findOne({ email: email });
  } catch {
    const error = new Error("Error! Something went wrong.");
    return next(error);
  }
  if (!existingUser || existingUser.password != password) {
    const error = Error("Wrong details please check at once");
    return next(error);
  }
  let token;
  try {
    //Creating jwt token
    token = jwt.sign(
      { userId: existingUser.id, email: existingUser.email },
      "secretkeyappearshere",
      { expiresIn: "1h" }
    );
  } catch (err) {
    console.log(err);
    const error = new Error("Error! Something went wrong.");
    return next(error);
  }
 
  res
    .status(200)
    .json({
      success: true,
      data: {
        userId: existingUser.id,
        email: existingUser.email,
        token: token,
      },
    });
});
 
// Handling post request
app.post("/signup", async (req, res, next) => {
  const { name, email, password } = req.body;
  const newUser = User({
    name,
    email,
    password,
  });
 
  try {
    await newUser.save();
  } catch {
    const error = new Error("Error! Something went wrong.");
    return next(error);
  }
  let token;
  try {
    token = jwt.sign(
      { userId: newUser.id, email: newUser.email },
      "secretkeyappearshere",
      { expiresIn: "1h" }
    );
  } catch (err) {
    const error = new Error("Error! Something went wrong.");
    return next(error);
  }
  res
    .status(201)
    .json({
      success: true,
      data: { userId: newUser.id, 
          email: newUser.email, token: token },
    });
});
 
//Connecting to the database
mongoose
  .connect("mongodb://localhost:27017/testDB")
  .then(() => {
    app.listen("3000", () => {
      console.log("Server is listening on port 3000");
    });
  })
  .catch((err) => {
    console.log("Error Occurred");
  });

输出: 我们正在使用Postman测试我们的API,我们已经在请求体中提供了注册的数据,最后,获取了我们的令牌以及其他一些详细信息。

如何在Express.js应用中实现JWT身份验证

步骤3:解码JWT Token

  • 我们可以通过带有令牌的请求来获取权限,这里我们展示了一个简单的示例来说明如何解码令牌。
  • 令牌通过请求头发送,我们在这里从授权头中提取令牌,我们使用split函数是因为令牌保持在“Bearer Token”的形式,我们只想提取令牌,所以提供了索引1。
  • verify方法接受令牌和jwt键,并提供令牌的解码。在此之后,我们可以获取用户的信息。
app.get('/accessResource', (req, res)=>{   
    const token = req.headers.authorization.split(' ')[1];  
    //Authorization: 'Bearer TOKEN'
    if(!token)
    {
        res.status(200).json({success:false, message: "Error!
                       Token was not provided."});
    }
    //Decoding the token
    const decodedToken = jwt.verify(token,"secretkeyappearshere" );
    res.status(200).json({success:true, data:{userId:decodedToken.userId,
     email:decodedToken.email});    
})

输出: 这里我们正在测试负责接收令牌的API,我们已经将令牌传递到头部,最终服务器成功解码了用户详细信息。

如何在Express.js应用中实现JWT身份验证

结论: 通过这个实例,我们成功地实现了从创建到解码的令牌。这个 ‘accessResource’ 路由的示例足以说明工作原理,您可以根据自己的需求在内部使用令牌,并相应地允许用户。所有这些意味着我们成功地能够持久化无状态HTTP请求的信息。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程