在Nodejs中使用JWT进行鉴权

这篇具有很好参考价值的文章主要介绍了在Nodejs中使用JWT进行鉴权。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

什么是 JSON Web Token(JWT)?

JSON Web Token(JWT)是一种用于在web上传递信息的标准,它以JSON格式表示信息,通常用于身份验证和授权。

JWT由三个部分组成:Header(头部)、Payload(负载)和Signature(签名)。它们用点号分隔开,形成了一个JWT令牌。

JWT 的基本结构

  • Header

Header(头部)是JWT结构的第一部分,它是一个包含关于令牌的元数据的JSON对象。Header通常包含两个主要字段:algtyp

alg(Algorithm)字段:这个字段指定了用于签名JWT的加密算法。它可以是以下之一:

  • HS256:HMAC-SHA256,使用密钥进行对称加密。
  • RS256:RSA-SHA256,使用RSA密钥对进行非对称加密。
  • ES256:ECDSA-SHA256,使用椭圆曲线数字签名算法进行非对称加密,等等。

typ(Type)字段:这个字段表示令牌的类型。对于JWT,这个字段的值通常是**JWT**,用于指示这是一个JSON Web Token。

一个简单的 JWT 头可以是下面这样:

{
    "typ":"JWT",
    "alg":"HS256"
 }
  • Payload

Payload(负载)用于存储实际的用户数据和其他相关信息。Payload是一个包含键值对的JSON对象,它包含了有关JWT令牌的有用信息。

JWT 规定了7个官方字段:

- iss (issuer):签发人
- exp (expiration time):过期时间
- sub (subject):主题
- aud (audience):受众
- nbf (Not Before):生效时间
- iat (Issued At):签发时间
- jti (JWT ID):编号

除了官方字段,你还可以在这个部分定义私有字段,一个Payload如下所示:

 {
  "userId":"123",
  "iss": "your_app",
  "sub": "user123",
  "role": "admin",
  "exp": 1699999999
 }
  • Signature

JWT的Signature(签名)是JWT令牌的第三个部分,用于确保令牌的完整性和来源验证。Signature是通过将Header和Payload的组合(不包括分隔符**.**)与一个密钥进行加密或哈希生成的值。

Signature生成方式:

HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)

一个JWT示例

Header:
{
  "alg" : "HS256",

  "typ" : "JWT"
}

Payload:
{
  "id" : 123,

  "name" : "test"
}

Secret: your_secret

Header(经过Base64编码):

eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9

Payload(经过Base64编码):

eyJpZCI6IDEyMywgIm5hbWUiOiAidGVzdCJ9

使用提供的Secret对原始的Header和原始的Payload进行加密生成Signature:

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  "your_secret"
)

完整的的token需要吧这三部分拼起来如下:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MTIzLCJuYW1lIjoidGVzdCJ9.oMyOEgY
iZosc0HYCkIjrqh_DH3CLlmIkIjOe-icpTg8

在Nodejs中使用JWT

1,环境配置

我们先来配置一下环境,首先初始化一个package.json文件存放我们用到的npm包:

npm init -y

然后安装jsonwebtoken和express:
npm install express jsonwebtoken

2,创建一个基础的服务器

const express = require('express');
const jwt = require('jsonwebtoken');
const app = express();

app.use(express.json());

const PORT = 3000;
app.listen(PORT, () => {
    console.log(`Server is running on ${PORT} ...`);
});

这里我们使用了**express.json**这个中间件,express.json() 是一个 Express 中间件函数,用于解析传入请求体中的 JSON 数据。当客户端向服务器发送带有 JSON 数据的 POST 请求时,express.json() 中间件将从请求体中解析出 JSON 数据,并将其添加到到 req.body 上。

3,在登录之后下发token

// 用户数据
const users = [
    { id: 1, username: "user1", password: "password1" },
    { id: 2, username: "user2", password: "password2" }
];
const jwtSecretKey = "your_jwt_secret_key";

// 登录之后生成 JWT token
app.post("/user/login", async (req, res) => {
    try {
        const { username, password } = req.body;
        const user = users.find(u => u.username === username && u.password === password);

        if (!user) {
            return res.status(401).json({ error: "用户名或密码错误" });
        }

        const payload = {
            userId: user.id,
        };
        //生成token 设置过期时间为 1 小时
        const token = await jwt.sign(payload, jwtSecretKey, { expiresIn: '1h' });
        res.json({ token });
    } catch (error) {
        res.status(500).json({ error: "登录失败" });
    }
});

为了演示,我们的用户数据是写死的

/user/login路由会在用户名和密码通过校验之后,使用jwt.sign生成一个token,并且设置过期时间为一个小时

jwt.sign 函数用于创建一个 JWT 令牌,它接受一个payload,并使用给定的密钥将其签名生成一个令牌字符串。

以下是 jwt.sign 的基本用法以及其参数:

jwt.sign(payload, secretOrPrivateKey, [options, callback])
  • payload:要存储在token中的数据,通常是一个 JavaScript 对象,可以包含任意信息。
  • secretOrPrivateKey:用于对令牌进行签名的密钥。
  • options(可选):一个包含选项的对象,用于配置生成的 JWT。常见的选项包括 expiresIn(过期时间)和 algorithm(签名算法)等。
  • callback(可选):一个回调函数,用于异步生成 JWT。

然后使用curl请求该路由,响应内容如下:
在Nodejs中使用JWT进行鉴权,JavaScript,node.js,前端,鉴权

4,创建isLogin中间件

async function isLogin(req, res, next) {
    const tokenHeaderKey = 'Authorization';
    const token = req.header(tokenHeaderKey)

    if (!token) {
        return res.status(401).json({ error: "用户未登录" });
    }

    const verified = await jwt.verify(token, jwtSecretKey);
    if (verified) {
        next()
    } else {
        return res.status(401).json({ error: "无效的token" });
    }
}

isLogin 是一个用于验证用户是否已登录的中间件。它首先从请求头中获取 Authorization 字段的值,该值应该是 JWT 令牌。然后使用 jwt.verify 函数验证令牌的有效性。如果验证通过,将调用 next(),表示用户已登录,然后继续执行后续的路由处理程序。如果验证失败,返回 401 状态码,表示令牌无效。

5,创建需要身份验证的路由

// 获取用户信息
app.get("/user/:username", isLogin, async (req, res) => {
    const username = req.params.username;
    const user = users.find(u => u.username === username).map(u => ({ id: u.id, username: u.username}));
    res.json(user);
});

**/user/:username**是一个用于获取用户信息的路由。路由中的 :username 表示参数,表示用户的用户名。

我们在这个路由中添加了两个中间件,首先通过 isLogin 中间件验证用户是否已登录。如果用户已登录,才会进入到下一个中间件,然后根据用户名从 users 数组中查找用户信息并作为响应。

然后使用curl请求该路由,就能拿到用户信息:

在Nodejs中使用JWT进行鉴权,JavaScript,node.js,前端,鉴权

6,使用axios携带token请求用户信息

import axios from "axios";
const token = localStorage.getItem("token");
const url = "http://localhost:3000/user/your_username"
const headers = {
    "Authorization": token,
    "Content-Type": "application/json",
    "Accept": "application/json",
};
const getUserInfo = () => {
    axios.get(url, { headers: headers })
        .then((response) => {
            console.log(response);
        })
        .catch((error) => {
            console.log(error);
        });
}

在前端我们一般会使用axios来发起请求,只要把token的值放在http header中的Authorization字段即可。当然除了放在Authorization之外,也可以放在其他header字段中,不过后端也需要从对应的header字段取token。

完整代码:

const express = require('express');
const jwt = require('jsonwebtoken');
const app = express();

app.use(express.json());

const PORT = 3000;
app.listen(PORT, () => {
    console.log(`Server is up and running on ${PORT} ...`);
});

// 用户数据
const users = [
    { id: 1, username: "user1", password: "password1" },
    { id: 2, username: "user2", password: "password2" }
];
const jwtSecretKey = "your_jwt_secret_key";

// 登录之后生成 JWT token
app.post("/user/login", async (req, res) => {
    try {
        const { username, password } = req.body;
        
        const user = users.find(u => u.username === username && u.password === password);

        if (!user) {
            return res.status(401).json({ error: "用户名或密码错误" });
        }

        const payload = {
            userId: user.id,
        };
        //生成token 设置过期时间为 1 小时
        const token = await jwt.sign(payload, jwtSecretKey, { expiresIn: '1h' });
        res.json({ token });
    } catch (error) {
        res.status(500).json({ error: "登录失败" });
    }
});

async function isLogin(req, res, next) {
    const tokenHeaderKey = 'Authorization';
    const token = req.header(tokenHeaderKey)

    if (!token) {
        return res.status(401).json({ error: "用户未登录" });
    }

    const verified = await jwt.verify(token, jwtSecretKey);
    if (verified) {
        next()
    } else {
        return res.status(401).json({ error: "无效的token" });
    }
}
// 获取用户信息
app.get("/user/:username", isLogin, async (req, res) => {
    const username = req.params.username;
    const user = users.map(u => ({ id: u.id, username: u.username})).find(u => u.username === username)
    res.json(user);
});

总结

这篇文章我们介绍了JWT原理以及在nodejs中使用JWT 进行鉴权,除了JWT之外还可以使用session管理用户状态,感兴趣的可以👇这里:https://blog.csdn.net/AC_greener/article/details/130036699

参考文章:

https://github.com/auth0/node-jsonwebtoken

https://www.ruanyifeng.com/blog/2018/07/json_web_token-tutorial.html
在Nodejs中使用JWT进行鉴权,JavaScript,node.js,前端,鉴权文章来源地址https://www.toymoban.com/news/detail-683093.html

到了这里,关于在Nodejs中使用JWT进行鉴权的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 将 Jupyter Notebook 用于 JavaScript (使用 Node.js 或 Deno 环境)

    熟悉 Python 的读者, 可能同样对 IPython 或 Jupyter 等项目 (如 Jupyter Notebook) 有所耳闻. 正如其名, IPython 项目让 Python 这门语言变得 “interactive”; 如: 交互式的 Shell 程序, 对交互式数据可视化以及 GUI 工具集的支持等等 (具体可见 IPython 项目的网站). 比如在 Notebook 中, 用户可以实现

    2024年02月07日
    浏览(42)
  • nodejs使用JWT(全)

    token表示令牌,用户的登录凭证。 基于 Token 的身份验证方法,使用基于 Token 的身份验证方法,在服务端不需要存储用户的登录记录。大概的流程是这样的: 客户端使用用户名 跟密码请求登录 服务端收到请求,去验证用户名与密码 验证成功后,服务端会签发一个 Token,再把

    2024年02月08日
    浏览(26)
  • Node.js环境调用百度智能云(百度云)api鉴权认证三步走

    Postman脚本下载 下载Postman pre-request Script 设置 Authorization 示例脚本 签名计算工具 https://cloud.baidu.com/signature/index.html 百度智能云提供了在线生成签名工具,用户仅需填写必要请求信息、访问密钥(包含访问密钥ID(AK)和秘密访问密钥(SK)),可快速生成认证字符串。 文档地址 https:

    2024年04月11日
    浏览(35)
  • 【Nodejs】Node.js开发环境安装

    在命令窗口中输入 node -v 可以查看版本 0.x 完全不技术 ES6 4.x 部分支持 ES6 特性 5.x 部分支持ES6特性(比4.x多些),属于过渡产品,现在来说应该没有什么理由去用这个了 6.x 支持98%的 ES6 特性 8.x 支持 ES6 特性 去 Node.js 的官网下载安装包: 我们也可以下载历史版本。 后续如果

    2024年02月15日
    浏览(73)
  • Node.js | 使用 zlib 内置模块进行 gzip 压缩

    🖥️ NodeJS专栏:Node.js从入门到精通 🖥️ 博主的前端之路:前端之行,任重道远(来自大三学长的万字自述) 🧧 加入社区领红包:海底烧烤店ai(从前端到全栈) 🧑‍💼个人简介:即将大三的学生,一个不甘平庸的平凡人🍬 👉 你的一键三连是我更新的最大动力❤️!

    2024年02月02日
    浏览(51)
  • 微信小程序一键登录功能,使用uni-app和springboot(JWT鉴权)

    目录 概述 微信登录接口说明  关于获取微信用户的信息 前端代码(uni-app) 后端代码(SpringBoot) 配置文件:application.yml  配置文件:Pom.xml  类:WeChatModel    类:WeChatSessionModel  类:UserInfoController 业务层实现类:UserInfoServiceImpl 工具类:JWTUtils 拦截器配置-自定义拦截器

    2024年02月09日
    浏览(72)
  • 【nodejs】用Node.js实现简单的壁纸网站爬虫

    在这个博客中,我们将学习如何使用Node.js编写一个简单的爬虫来从壁纸网站获取图片并将其下载到本地。我们将使用Axios和Cheerio库来处理HTTP请求和HTML解析。 首先,确保你已经安装了Node.js环境。然后,我们将创建一个新的文件夹,初始化项目并安装所需的依赖库: 编写爬虫

    2024年02月12日
    浏览(44)
  • 「NodeJs进阶」超全面的 Node.js 性能优化相关知识梳理

    相信对于前端同学而言,我们去开发一个自己的简单后端程序可以借助很多的nodeJs的框架去进行快速搭建,但是从前端面向后端之后,我们会在很多方面会稍显的有些陌生,比如「性能分析」,「性能测试」,「内存管理」,「内存查看」,「使用C++插件」,「子进程」,「

    2024年02月01日
    浏览(52)
  • 使用WebApi+Vue3从0到1搭建《权限管理系统》:二、搭建JWT系统鉴权

    视频地址:【WebApi+Vue3从0到1搭建《权限管理系统》系列视频:搭建JWT系统鉴权-哔哩哔哩】 https://b23.tv/R6cOcDO qq群:801913255 一、在appsettings.json中设置鉴权属性 二、新建模型 添加模型JwtSettingModel其中字段和appsettings.json中的字段一样,如下 三、新建解析appsettings.json节点的帮助类

    2024年04月22日
    浏览(36)
  • Nodejs 入门8 NeDB 轻量级的Node.js 数据库

    常用的sqlite轻量级数据库,nodejs在windows环境下安装配置有时候会比较麻烦,很难顺利安装。 Nedb(Node Embedded Database)在一些情况下可以替代sqlite,特别适用于小型项目和快速原型开发。本文将介绍Nedb的基本概念、特性和使用方法,以帮助大家更好地了解和利用这个便捷的工

    2024年01月22日
    浏览(62)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包