手记

JWT 用户校验课程:从零开始的全面指南

概述

本文提供了从零开始的JWT用户校验课程,详细介绍了JWT的概念、工作原理和优势,涵盖生成、验证JWT以及JWT在用户认证和授权中的应用案例。此外,文章还讨论了JWT的安全使用方法和常见问题的解决方案。JWT 用户校验课程旨在帮助开发者全面掌握JWT技术。

JWT 用户校验课程:从零开始的全面指南
JWT 简介

什么是 JWT(JSON Web Token)

JSON Web Token(JWT)是一种开放标准(RFC 7519),用于在网络应用环境中传输对称加密或非对称加密的信息。JWT 主要用于解决现有的一些认证和授权问题,它能够安全地传输用户信息,而无需频繁地调用服务器来验证用户身份。

JWT 由三部分组成,它们之间用点(.)分隔:

  1. 头部(Header):描述了令牌的类型以及所使用的签名算法。
  2. 负载(Payload):负载包含在 JWT 内的声明。声明是关于实体(人、地方、事物、活动)的声明,声明由键值对组成。
  3. 签名(Signature):签名用来验证消息的发送方是否合法以及消息是否被篡改。

JWT 的工作原理

JWT 的工作原理基于以下步骤:

  1. 生成 JWT:客户端通过发送用户名和密码等信息向服务器请求一个 JWT。
  2. 验证用户信息:服务器验证用户信息的正确性。
  3. 生成并返回 JWT:如果验证成功,服务器会生成一个 JWT 并将其返回给客户端。
  4. 保存 JWT:客户端收到 JWT 后,可以将其保存在本地,例如 localStorage 或内存中。
  5. 发送 JWT:客户端每次请求时,都需要将 JWT 通过 HTTP 请求头中的 Authorization 字段发送给服务器。
  6. 验证 JWT:服务器收到请求后,会检查 JWT 是否有效,包括是否过期以及签名是否正确。
  7. 授权访问:如果 JWT 有效,服务器会允许客户端访问受保护的资源。

JWT 的优势和应用场景

JWT 的主要优势包括:

  • 简洁性:JWT 的结构简洁,易于理解和实现。
  • 安全性:JWT 使用签名机制确保数据传输过程中的完整性。
  • 跨域支持:JWT 可以跨域使用,无需额外的服务器状态支持。
  • 轻量级:JWT 不需要额外的数据库支持,只需要在客户端保存 JWT 即可。

JWT 的应用场景包括:

  • 用户认证:使用 JWT 进行用户身份验证,取代传统的会话认证。
  • 授权:JWT 可以携带授权信息,服务器可以根据 JWT 中携带的信息来决定是否授权访问。
  • 信息交换:JWT 可以用来安全地交换信息,特别是在前后端交互中。
设置开发环境

安装必要的工具和库

为了生成和验证 JWT,你需要在你的开发环境中安装一些必要的库。这里以 Node.js 进行演示。

  1. 安装 Node.js:确保你的计算机上安装了 Node.js。你可以从官网下载最新版本的 Node.js,网址为 https://nodejs.org
  2. 安装 JWT 库:在你的项目目录中,打开命令行工具,运行以下命令安装 jsonwebtoken 库:
    npm install jsonwebtoken

配置开发环境

为了更好地进行 JWT 的开发,你需要设置一个简单的 Node.js 服务器,并确保它能够生成和验证 JWT。

  1. 创建项目目录
    mkdir jwt-course
    cd jwt-course
  2. 初始化项目
    npm init -y
  3. 安装依赖

    npm install express jsonwebtoken
  4. 创建服务器文件
    创建一个 server.js 文件,并在其内部设置一个简单的 Express 服务器。

    const express = require('express');
    const jwt = require('jsonwebtoken');
    const app = express();
    const port = 3000;
    
    const secret = 'mysecretkey'; // 定义密钥
    
    app.listen(port, () => {
       console.log(`Server running on port ${port}`);
    });
创建并发放 JWT

编写代码生成 JWT

在服务器中,你需要写一段代码来生成 JWT。该代码将包含用户的 ID、用户名等信息,并使用私钥对 JWT 进行签名。

  1. 定义密钥:在代码中定义一个密钥,用于生成和验证 JWT。
    const secret = 'mysecretkey';
  2. 生成 JWT:在你需要生成 JWT 的 REST API 端点中编写代码。
    app.post('/login', (req, res) => {
       const user = {
           id: 1,
           username: 'testuser'
       };
       const token = jwt.sign(user, secret, { expiresIn: '1h' });
       res.json({ token });
    });

测试生成的 JWT 是否有效

为了确保 JWT 工作正常,你需要写一段代码来解析并验证 JWT。

  1. 解析 JWT:在需要验证 JWT 的 REST API 端点中编写代码。
    app.get('/protected', (req, res) => {
       const token = req.headers.authorization.split(' ')[1];
       if (!token) {
           return res.status(401).json({ message: 'No token provided' });
       }
       jwt.verify(token, secret, (err, decoded) => {
           if (err) {
               return res.status(401).json({ message: 'Invalid token' });
           }
           res.json({ message: `Welcome ${decoded.username}` });
       });
    });
JWT 用户校验实现

接收并解析 JWT

当客户端向服务器发送请求时,它通常会将 JWT 附加在请求头中。你需要在服务器端接收并解析这些 JWT。

  1. 提取 JWT:在需要验证 JWT 的 REST API 端点中,从请求头中提取 JWT。
    const token = req.headers.authorization.split(' ')[1];
  2. 验证 JWT 是否有效:使用 jsonwebtoken 库的 verify 方法验证 JWT。
    jwt.verify(token, secret, (err, decoded) => {
       if (err) {
           return res.status(401).json({ message: 'Invalid token' });
       }
       // JWT 有效,继续处理请求
    });
  3. 从 JWT 中解析用户信息:一旦 JWT 通过验证,你可以从 JWT 的负载中提取用户信息,例如用户 ID 和用户名。
    const user = decoded;
    console.log(user); // { id: 1, username: 'testuser' }
实际应用案例

使用 JWT 进行用户认证

使用 JWT 进行用户认证是其最常见也是最重要的应用场景。以下是一个简单的示例,展示了如何使用 JWT 实现用户登录和访问受保护资源的功能。

用户登录端点

app.post('/login', (req, res) => {
    const user = {
        id: 1,
        username: 'testuser'
    };
    const token = jwt.sign(user, secret, { expiresIn: '1h' });
    res.json({ token });
});

访问受保护资源端点

app.get('/protected', (req, res) => {
    const token = req.headers.authorization.split(' ')[1];
    if (!token) {
        return res.status(401).json({ message: 'No token provided' });
    }
    jwt.verify(token, secret, (err, decoded) => {
        if (err) {
            return res.status(401).json({ message: 'Invalid token' });
        }
        res.json({ message: `Welcome ${decoded.username}` });
    });
});

JWT 在前后端交互中的应用

在前后端交互中,JWT 可以用来传递用户信息,从而实现无状态的认证和授权。以下是一个简单的例子,展示了前端如何使用 JWT 访问后端受保护的资源。

前端请求示例

fetch('/protected', {
    method: 'GET',
    headers: {
        'Authorization': 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw1'
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));

后端验证示例

const token = req.headers.authorization.split(' ')[1];
jwt.verify(token, secret, (err, decoded) => {
    if (err) {
        return res.status(401).json({ message: 'Invalid token' });
    }
    console.log(decoded); // 解析后的用户信息
    res.json({ message: `Welcome ${decoded.username}` });
});
常见问题及解决方案

JWT 过期处理

JWT 通常会有一个过期时间(例如 1 小时),当 JWT 过期时,客户端需要重新获取一个新的 JWT。这里介绍一种常见的处理过期 JWT 的方法。

  1. 前端处理:前端在每次请求时,检查 JWT 是否过期,并在过期时重新获取新的 JWT。

    function checkTokenExpiration(token) {
       const decoded = jwt.decode(token);
       const currentTime = Math.floor(Date.now() / 1000);
       return decoded.exp > currentTime;
    }
    
    const token = localStorage.getItem('token');
    if (!token || !checkTokenExpiration(token)) {
       // 重新获取 JWT
       fetch('/login', {
           method: 'POST',
           headers: { 'Content-Type': 'application/json' },
           body: JSON.stringify({ username: 'testuser', password: 'testpassword' })
       })
       .then(response => response.json())
       .then(data => {
           localStorage.setItem('token', data.token);
           // 使用新获取的 JWT 继续请求
       });
    }
  2. 后端处理:如果客户端发送了一个过期的 JWT,后端需要返回 401 状态码,客户端根据返回的错误信息重新获取 JWT。
    jwt.verify(token, secret, (err, decoded) => {
       if (err && err.name === 'TokenExpiredError') {
           return res.status(401).json({ message: 'Token expired' });
       }
       // JWT 有效,继续处理请求
    });

如何安全地使用 JWT

为了确保 JWT 的安全性,你需要遵循以下几个原则:

  1. 使用 HTTPS:确保 JWT 在传输过程中被加密,以防止中间人攻击。
  2. 安全存储:不要将 JWT 存储在浏览器的本地存储或 Cookie 中,而是使用 HTTP-only Cookie。
  3. 密钥保护:确保 JWT 的密钥是安全的,不要泄露给未经授权的用户。
  4. 刷新 token:在 JWT 过期前,客户端可以请求刷新 token,以延长会话的有效时间。

使用 HTTP-only Cookie 存储 JWT

// 设置 HTTP-only Cookie
res.cookie('token', token, {
    httpOnly: true,
    secure: true, // 生产环境中一定要设置为 true
    maxAge: 3600000 // 过期时间 1 小时
});

// 从前端获取 Cookie 中的 JWT
document.cookie.split('; ').forEach(cookie => {
    const [name, value] = cookie.split('=');
    if (name === 'token') {
        console.log(value);
    }
});

问题排查和调试技巧

在使用 JWT 过程中,可能会遇到各种问题,以下是一些排查和调试技巧:

  1. 检查 JWT 有效载荷:确保 JWT 的 payload 中包含正确的信息,例如用户 ID 和用户名。
  2. 检查签名算法:确保 JWT 的签名算法与验证算法一致。
  3. 检查 JWT 过期时间:确保 JWT 的过期时间设置合理,不要设置太短或太长。
  4. 使用调试工具:使用浏览器开发者工具或 Postman 等工具调试 JWT 请求,查看请求头和响应体。
0人推荐
随时随地看视频
慕课网APP