Part6.商业解方奥秘:API 接口鉴权保障方案(6/7)

JSON Web Token 方案详解

JSON Web Token(JWT)是一种开放标准(RFC 7519),用于在网络应用环境中以简短的方式安全地传递信息。JWT 常用于身份验证和信息交换,因其紧凑性和自包含性,广泛应用于现代 Web 应用程序和单页面应用(SPA)中。

JWT 的基本结构

JWT 由三部分组成,每一部分之间用句点(.)分隔:

  1. 头部(Header): 通常由两个部分组成:

    • typ:令牌类型,一般为 "JWT"。
    • alg:签名算法,例如 HS256(HMAC SHA-256)或 RS256(RSA SHA-256)。

    示例

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

    经过 Base64Url 编码后,生成 JWT 头部。

  2. 载荷(Payload): 载荷中包含声明(claims),声明是关于实体(通常是用户)和其他数据的键值对。常见的声明有:

    • 注册声明:包含一些预定义的声明,如 sub(主题)、exp(过期时间)、iat(发行时间)等。
    • 公共声明:可定义自己的声明,需避免与其他人冲突。
    • 私有声明:自己定义的声明,适用于特定场景。

    示例

    {
        "sub": "1234567890",
        "name": "John Doe",
        "admin": true,
        "iat": 1516239022
    }
    

    载荷同样经过 Base64Url 编码,形成 JWT 的第二部分。

  3. 签名(Signature): 为了生成签名部分,需要将编码后的头部和载荷以及一个密钥,使用指定的算法进行签名。这个过程确保了 JWT 的完整性和真实性。

    示例

    HMACSHA256(
        base64UrlEncode(header) + "." +
        base64UrlEncode(payload),
        your-256-bit-secret
    )
    

JWT 的工作原理

  1. 用户通过用户名和密码等凭据进行身份验证。
  2. 服务器验证用户的凭据,生成 JWT,并将其返回给用户。JWT 通过 Base64Url 编码而成。
  3. 用户存储 JWT,通常存储在浏览器的 localStoragesessionStorage 中。
  4. 用户在每次请求时将 JWT 发送到服务器,通常通过 HTTP 请求的 Authorization 头部。
  5. 服务器接收到 JWT 后验证其签名与内容。如果有效,服务器执行该请求;如果无效,返回相应的错误信息。

JWT 的优势

  1. 无状态:JWT 以自包含的方式存储用户信息,服务器不需要存储用户会话信息,适合分布式系统。
  2. 跨域支持:由于 JWT 是基于标准的字符串格式,可以轻松支持跨域请求。
  3. 灵活性:可以在 Token 中存储自定义数据,不仅限于身份验证相关的信息。
  4. 安全性:通过签名算法保证数据的完整性,避免被篡改。

JWT 的缺点

  1. 不可撤销性:JWT 一旦生成,无法简单地撤销,除非设计了 Token 刷新机制。
  2. 过期管理:需要合理设置过期时间,过长会带来安全隐患,过短则可能影响用户体验。
  3. 隐私问题:JWT 中的信息是Base64Url编码的,并未加密,因此敏感信息不应直接放在 Token 中。

常见用例

  • 用户身份验证:用户登录成功后,会话管理通过发放 JWT 实现。
  • API 访问控制:保护 API 端点,确保只有持有有效 Token 的用户才能访问。
  • 单点登录(SSO):多个系统之间共享 JWT,实现单点登录。

总结

JWT 是一种简单、高效且灵活的身份验证和信息交换机制,其无状态和自包含的特点使其成为现代 Web 应用程序中广泛使用的身份认证方案。尽管存在一些缺点,但通过合理的设计和实现,可以充分发挥 JWT 的优势。

jsonwebtoken 模块:API 全解析

jsonwebtoken 是一个流行的 Node.js 模块,用于生成和验证 JSON Web Tokens (JWT)。它提供了简单易用的 API,使得在 Node.js 应用程序中实现 JWT 身份验证变得非常方便。以下是 jsonwebtoken 模块的主要 API 及其使用方法。

安装

首先,你需要通过 npm 安装 jsonwebtoken 模块:

npm install jsonwebtoken

主要 API

1. jwt.sign(payload, secretOrPrivateKey, [options, callback])

生成一个 JWT。

  • payload: 要编码到 JWT 中的数据,可以是对象或字符串。
  • secretOrPrivateKey: 用于签名 JWT 的密钥或私钥。
  • options: 可选参数,包含以下常用选项:
    • algorithm (默认: HS256): 签名算法。
    • expiresIn: 令牌的过期时间,例如 60"2 days""10h""7d"
    • notBefore: 令牌生效时间。
    • audience: 令牌的受众。
    • issuer: 令牌的发行者。
    • jwtid: 令牌的唯一标识符。
    • subject: 令牌的主题。
    • noTimestamp: 如果为 true,则不包含 iat (issued at) 声明。
    • header: 自定义 JWT 头部。
  • callback: 可选的回调函数,用于异步生成 JWT。

示例

const jwt = require('jsonwebtoken');

const payload = { userId: 123, name: 'John Doe' };
const secretKey = 'your-secret-key';

// 同步生成 JWT
const token = jwt.sign(payload, secretKey, { expiresIn: '1h' });
console.log(token);

// 异步生成 JWT
jwt.sign(payload, secretKey, { expiresIn: '1h' }, (err, token) => {
    if (err) throw err;
    console.log(token);
});

2. jwt.verify(token, secretOrPublicKey, [options, callback])

验证并解码一个 JWT。

  • token: 要验证的 JWT。
  • secretOrPublicKey: 用于验证 JWT 的密钥或公钥。
  • options: 可选参数,包含以下常用选项:
    • algorithms: 允许的签名算法数组。
    • audience: 验证令牌的受众。
    • issuer: 验证令牌的发行者。
    • ignoreExpiration: 如果为 true,则忽略令牌的过期时间。
    • ignoreNotBefore: 如果为 true,则忽略令牌的生效时间。
    • subject: 验证令牌的主题。
    • clockTolerance: 允许的时间偏差,单位为秒。
    • maxAge: 令牌的最大有效期。
    • clockTimestamp: 当前时间戳,用于验证令牌的过期时间。
  • callback: 可选的回调函数,用于异步验证 JWT。

示例

const jwt = require('jsonwebtoken');

const token = 'your-jwt-token';
const secretKey = 'your-secret-key';

// 同步验证 JWT
try {
    const decoded = jwt.verify(token, secretKey);
    console.log(decoded);
} catch (err) {
    console.error('Token verification failed:', err.message);
}

// 异步验证 JWT
jwt.verify(token, secretKey, (err, decoded) => {
    if (err) {
        console.error('Token verification failed:', err.message);
        return;
    }
    console.log(decoded);
});

3. jwt.decode(token, [options])

解码一个 JWT,但不进行验证。

  • token: 要解码的 JWT。
  • options: 可选参数,包含以下常用选项:
    • complete: 如果为 true,则返回包含头部和载荷的对象。
    • json: 如果为 true,则强制解析载荷为 JSON。

示例

const jwt = require('jsonwebtoken');

const token = 'your-jwt-token';

// 解码 JWT
const decoded = jwt.decode(token, { complete: true });
console.log(decoded);

示例应用

以下是一个简单的 Express 应用示例,展示了如何使用 jsonwebtoken 进行用户身份验证:

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

const app = express();
const secretKey = 'your-secret-key';

app.use(bodyParser.json());

// 模拟用户数据库
const users = [
    { id: 1, username: 'user1', password: 'password1' },
    { id: 2, username: 'user2', password: 'password2' }
];

// 登录接口
app.post('/login', (req, res) => {
    const { username, password } = req.body;
    const user = users.find(u => u.username === username && u.password === password);

    if (!user) {
        return res.status(401).json({ message: 'Invalid credentials' });
    }

    const token = jwt.sign({ userId: user.id }, secretKey, { expiresIn: '1h' });
    res.json({ token });
});

// 受保护的接口
app.get('/protected', (req, res) => {
    const token = req.headers['authorization'];

    if (!token) {
        return res.status(401).json({ message: 'No token provided' });
    }

    jwt.verify(token, secretKey, (err, decoded) => {
        if (err) {
            return res.status(403).json({ message: 'Failed to authenticate token' });
        }

        res.json({ message: 'Welcome to the protected route', user: decoded });
    });
});

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

总结

jsonwebtoken 模块提供了简单而强大的 API,使得在 Node.js 应用中实现 JWT 身份验证变得非常容易。通过 jwt.sign 生成 JWT,通过 jwt.verify 验证 JWT,可以有效地保护你的 API 和资源。

JWT 操作:创建、签发、解码与验证

JSON Web Token (JWT) 的创建与签发、解码与验证是 JWT 身份验证流程中的核心步骤。以下是这些步骤的详细说明及其在代码中的实现。

1. JWT 创建与签发

JWT 的创建与签发涉及生成一个包含用户信息的令牌,并使用密钥对其进行签名,以确保数据的完整性和真实性。

使用 jsonwebtoken 模块

在 Node.js 中,可以使用 jsonwebtoken 模块来创建和签发 JWT。

示例代码

const jwt = require('jsonwebtoken');

// 用户信息
const user = {
    id: 123,
    username: 'john_doe',
    role: 'admin'
};

// 密钥
const secretKey = 'your-secret-key';

// 生成 JWT
const token = jwt.sign(user, secretKey, { expiresIn: '1h' });

console.log('Generated JWT:', token);

代码说明

  1. 用户信息:定义一个包含用户信息的 JavaScript 对象,这些信息将被编码到 JWT 的载荷部分。
  2. 密钥:定义一个用于签名的密钥。密钥可以是简单的字符串或复杂的加密密钥。
  3. 生成 JWT:使用 jwt.sign 方法生成 JWT。该方法接受三个参数:
    • user:要编码的用户信息。
    • secretKey:用于签名的密钥。
    • options:可选参数,例如 expiresIn 指定令牌的过期时间。

2. JWT 解码

JWT 解码涉及将 JWT 解析为其原始的头部和载荷部分,但不进行验证。通常用于调试或查看 JWT 的内容。

使用 jsonwebtoken 模块

示例代码

const jwt = require('jsonwebtoken');

const token = 'your-jwt-token';

// 解码 JWT
const decoded = jwt.decode(token, { complete: true });

console.log('Decoded JWT:', decoded);

代码说明

  1. JWT 令牌:准备要解码的 JWT 令牌。
  2. 解码 JWT:使用 jwt.decode 方法解码 JWT。该方法接受两个参数:
    • token:要解码的 JWT 令牌。
    • options:可选参数,例如 completetrue 时将返回包含头部和载荷的对象。

3. JWT 验证

JWT 验证涉及检查 JWT 的签名是否有效,以及 JWT 是否在有效期内。验证成功后,可以信任 JWT 中的信息。

使用 jsonwebtoken 模块

示例代码

const jwt = require('jsonwebtoken');

const token = 'your-jwt-token';
const secretKey = 'your-secret-key';

// 验证 JWT
jwt.verify(token, secretKey, (err, decoded) => {
    if (err) {
        console.error('Token verification failed:', err.message);
        return;
    }

    console.log('Valid JWT:', decoded);
});

代码说明

  1. JWT 令牌:准备要验证的 JWT 令牌。
  2. 密钥:准备用于验证的密钥。密钥必须与生成 JWT 时使用的密钥相同。
  3. 验证 JWT:使用 jwt.verify 方法验证 JWT。该方法接受三个参数:
    • token:要验证的 JWT 令牌。
    • secretKey:用于验证的密钥。
    • callback:回调函数,用于处理验证结果。如果验证失败,回调函数将接收到一个错误;如果验证成功,回调函数将接收到解码后的用户信息。

示例应用

以下是一个完整的示例,展示了如何在 Express 应用中实现 JWT 的创建、签发、解码和验证:

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

const app = express();
const secretKey = 'your-secret-key';

app.use(bodyParser.json());

// 模拟用户数据库
const users = [
    { id: 1, username: 'user1', password: 'password1' },
    { id: 2, username: 'user2', password: 'password2' }
];

// 登录接口
app.post('/login', (req, res) => {
    const { username, password } = req.body

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

前端求职突破计划 文章被收录于专栏

你是否渴望全面提升前端技能?本专栏将带你畅游前端世界!从 JS 深析趣谈,让你领略 JavaScript 的独特魅力;到前端工程漫话,掌握项目构建精髓。深入洞察框架原理,探索 Node 全栈开发。泛端开发趣闻,开启多端应用新视野;揭秘商业解方奥秘,把握行业趋势。高阶专题层层剖析,助你突破技术瓶颈。更有前端面试指南,为求职保驾护航。无论你是新手小白还是资深开发者,这里都有你需要的知识盛宴!

全部评论

相关推荐

野猪不是猪🐗:现在的环境就是这样,供远大于求。 以前卡学历,现在最高学历不够卡了,还要卡第一学历。 还是不够筛,于是还要求得有实习、不能有gap等等... 可能这个岗位总共就一个hc,筛到最后还是有十几个人满足这些要求。他们都非常优秀,各方面都很棒。 那没办法了,看那个顺眼选哪个呗。 很残酷,也很现实
点赞 评论 收藏
分享
评论
2
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务