Fastify 中的 JWT 身份验证

在创建 Web 应用程序时,身份验证是一个非常重要的方面。JWT(JSON Web Token)通过在服务器和客户端之间传输经过加密的 JSON 等信息来验证用户身份,已成为最常用的身份验证方法之一。

Fastify 是一个快速和低开销的 Web 框架,提供了丰富的插件和功能,并支持 JWT 身份验证。在本文中,我们将深入探讨 Fastify 中的 JWT 身份验证,了解其原理和实现方法,并介绍如何在 Fastify 项目中使用 JWT 身份验证。

JWT 基础知识

在介绍 Fastify 中的 JWT 身份验证之前,我们要先了解一些 JWT 的基础知识。

JWT 是一个基于 JSON 的开放式标准(RFC 7519),用于在网络上安全地传输信息。简单来说,它包含三个部分:header、payload 和 signature。

  • Header:包含两个属性,算法(algorithm)和类型(type)。
  • Payload:包含用户信息,如用户名、角色、权限等。
  • Signature:用于验证数据完整性和认证数据来源。

JWT 的特点是安全、无状态、易于传输和跨平台,因此在 Web 系统中得到了广泛的应用。常用的 JWT 库有 jsonwebtokenjwt-simplejose 等。

Fastify 提供了 fastify-jwt 插件来实现 JWT 身份验证。在安装该插件后,我们可以使用 fastify.jwt.sign() 方法来为用户生成 JWT 令牌,并使用 fastify.jwt.verify() 方法来验证该令牌。下面是具体的实现过程:

  1. 安装 fastify-jwt 模块

    npm install fastify-jwt
  2. 注册 fastify-jwt 插件

    const fastify = require('fastify')();
    
    fastify.register(require('fastify-jwt'), {
      secret: 'my-secret', // 设置 JWT 密钥
    });
  3. 生成 JWT 令牌

    fastify.post('/login', (request, reply) => {
      const { username, password } = request.body;
    
      // TODO: 根据用户名和密码验证用户
    
      const token = fastify.jwt.sign({ username });
    
      reply.send({ token });
    });
  4. 验证 JWT 令牌

    fastify.get('/protected', {
      preValidation: fastify.authenticate,
    }, (request, reply) => {
      reply.send({ message: `Hello, ${request.user.username}!` });
    });

    上面的 fastify.authenticate 方法会从请求头中提取 JWT 令牌,并使用密钥验证其合法性。如果验证通过,将用户信息存储在 request.user 中,我们可以在处理程序中使用它。

示例代码

下面是一个完整的 Fastify 示例应用程序,演示了如何实现 JWT 身份验证:

const fastify = require('fastify')();

fastify.register(require('fastify-jwt'), {
  secret: 'my-secret',
});

const users = [
  { id: 1, username: 'admin', password: 'admin123', roles: ['admin'] },
  { id: 2, username: 'user', password: 'user123', roles: ['user'] },
];

fastify.post('/login', (request, reply) => {
  const { username, password } = request.body;

  const user = users.find(u => u.username === username);

  if (!user || user.password !== password) {
    reply.status(401).send({ message: 'Incorrect username or password.' });
  } else {
    const { id, username, roles } = user;
    const token = fastify.jwt.sign({ id, username, roles });
    reply.send({ token });
  }
});

fastify.get('/protected', {
  preValidation: fastify.authenticate,
}, (request, reply) => {
  const { id, username, roles } = request.user;

  if (roles.includes('admin')) {
    reply.send({ message: `Hello, admin ${username} (${id})!` });
  } else {
    reply.send({ message: `Hello, ${username} (${id})!` });
  }
});

fastify.listen(3000, (err) => {
  if (err) {
    console.error(err);
    process.exit(1);
  }
  console.log('Server start on http://localhost:3000');
});

该应用程序包含两个路由:/login/protected/login 用于验证用户的用户名和密码,并生成 JWT 令牌;/protected 用于获取受保护的资源,需要先通过 JWT 身份验证。

在验证 JWT 令牌时,我们使用 fastify.authenticate 方法,该方法会自动提取请求头中的 JWT 令牌,并验证其合法性。如果验证通过,将用户信息保存在 request.user 中,我们可以在处理程序中使用它。

总结

本文介绍了 Fastify 中的 JWT 身份验证,包括 JWT 的基础知识和在 Fastify 项目中的实现方法。通过阅读本文,您应该已经了解了如何在 Fastify 项目中使用 JWT 身份验证,并可以根据具体需求进行定制化开发。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/659f5b59add4f0e0ff801dfa


纠错反馈