为了账号安全,请及时绑定邮箱和手机立即绑定

JWT实战:新手也能轻松掌握的JWT入门教程

概述

JWT实战涵盖了JWT的基本概念、工作原理、使用场景以及生成与验证的方法,提供了多个实战案例和常见问题的解决方法,帮助开发者深入了解和应用JWT技术。

1. JWT简介

1.1 什么是JWT

JWT (JSON Web Token) 是一种开放标准 (RFC 7519),用于在网络应用间安全地将信息作为JSON对象传输。它允许客户端与服务器之间进行安全的通信,而无需通过cookie或其他方式存储会话信息。JWT通常用于身份验证和信息交换。

JWT的结构包括三部分,按如下顺序组合在一起并用点隔开:

  1. Header:包含令牌类型和所使用的加密算法。
  2. Payload:包含声明信息,如用户ID、用户名等。
  3. Signature:将header和payload进行编码并使用密钥签名,用于验证数据未被篡改。

1.2 JWT的工作原理

JWT的工作过程如下:

  1. 生成JWT:服务器在接收到客户端的请求后,生成一个JWT。
  2. 发送JWT:生成的JWT被发送给客户端,客户端在需要验证身份时携带这个JWT。
  3. 验证JWT:服务器接收到请求后,验证JWT的签名是否有效。
  4. 响应请求:验证通过后,服务器根据请求处理逻辑,返回响应。

生成JWT的示例代码如下:

import jwt
import datetime

# 生成JWT示例
payload = {
    "user_id": "123",
    "username": "john_doe",
    "exp": datetime.datetime.utcnow() + datetime.timedelta(days=1)
}
token = jwt.encode(payload, 'my_secret_key', algorithm='HS256')
print('Generated JWT:', token)

# 验证JWT示例
try:
    decoded_jwt = jwt.decode(token, 'my_secret_key', algorithms=['HS256'])
    print('Decoded JWT:', decoded_jwt)
except jwt.ExpiredSignatureError:
    print('Token expired')
except jwt.InvalidTokenError:
    print('Invalid token')

1.3 JWT的组成部分

JWT的组成部分包括以下三个部分:

  1. Header

    • 类型(Type):指定了这个令牌是JWT。
    • 算法(Algorithm):指定了用于签名的加密算法,如HS256(HMAC SHA-256)。
    • 示例代码:
      {
      "typ": "JWT",
      "alg": "HS256"
      }
  2. Payload

    • 标准注册的声明(Registered Claims):如iss(发行者)、exp(过期时间)、nbf(不活跃之前)、iat(签发时间)、jti(JWT ID)等。
    • 预留声明(Reserved Claims):自定义的声明,可包含任何应用定义的声明。
    • 示例代码:
      {
      "iss": "http://example.com",
      "exp": 1300819380,
      "iat": 1300816380,
      "sub": "johndoe"
      }
  3. Signature

    • 通过将header和payload编码后,使用密钥进行签名。
    • 完整的签名生成代码示例:

      import jwt
      import base64
      
      # 生成JWT的完整示例
      header = {"typ": "JWT", "alg": "HS256"}
      payload = {"user_id": "123", "username": "john_doe", "exp": 1680201895}
      secret = 'my_secret_key'
      
      base64_header = base64.b64encode(str(header).encode('utf-8')).decode('utf-8')
      base64_payload = base64.b64encode(str(payload).encode('utf-8')).decode('utf-8')
      signature = jwt.sign({**header, **payload}, secret, algorithm='HS256')
      jwt_token = f'{base64_header}.{base64_payload}.{signature}'
      print('Generated JWT:', jwt_token)

2. JWT的使用场景

JWT可以在多种场景中使用,包括但不限于以下几种:

2.1 用户认证

JWT广泛用于用户认证。使用JWT进行身份验证时,用户登录后会收到一个JWT,该JWT包含用户的某些详细信息,如用户ID和用户名。客户端后续的所有请求都携带此JWT,服务器则根据JWT中的信息验证用户的身份。

2.2 信息交换

JWT可以用于安全地交换信息。例如,在微服务架构中,不同的服务之间可以通过JWT传递经过加密的数据,以确保数据的完整性和安全性。

2.3 API安全

JWT可以用于保护API。服务器可以要求客户端在调用API时提供有效的JWT,从而确保只有授权的用户才能访问API。

3. JWT的生成与验证

JWT的生成和验证是一个相对简单的过程,但需要理解其基本原理。

3.1 生成JWT

生成JWT的过程包括创建header、payload和签名。示例代码如下:

import jwt
import datetime

# 设定密钥
secret = 'my_secret_key'

# 构建header
header = {
    "typ": "JWT",
    "alg": "HS256"
}

# 构建payload
payload = {
    "user_id": "123",
    "username": "john_doe",
    "exp": datetime.datetime.utcnow() + datetime.timedelta(days=1)
}

# 生成JWT
encoded_jwt = jwt.encode(payload, secret, algorithm='HS256')
print(encoded_jwt)

安装jwt库的命令:

pip install pyjwt

3.2 验证JWT

验证JWT需要检查签名是否有效,并检查payload中的内容是否满足要求。示例代码如下:

import jwt

# 设置密钥
secret = 'my_secret_key'

# 解码JWT
try:
    decoded_jwt = jwt.decode(encoded_jwt, secret, algorithms=['HS256'])
    print('Decoded JWT:', decoded_jwt)
except jwt.ExpiredSignatureError:
    print('Token expired')
except jwt.InvalidTokenError:
    print('Invalid token')

3.3 JWT的有效期和刷新

JWT的有效期由payload中的exp(过期时间)字段指定。当JWT过期后,客户端需要重新登录或请求一个新的JWT。

刷新JWT的示例代码如下:

import jwt
import datetime

# 设置密钥
secret = 'my_secret_key'

# 刷新JWT
refresh_payload = {
    "user_id": "123",
    "username": "john_doe",
    "exp": datetime.datetime.utcnow() + datetime.timedelta(days=1)
}
refreshed_jwt = jwt.encode(refresh_payload, secret, algorithm='HS256')
print('Refreshed JWT:', refreshed_jwt)

4. JWT实战案例

4.1 实战案例一:用户登录验证

用户登录时,服务器生成JWT,并将JWT返回给客户端。客户端在后续请求中携带JWT,服务器验证JWT以确认用户身份。

示例代码:

import jwt
import datetime

# 用户登录请求
def login(username, password):
    # 模拟用户验证
    if username == 'john_doe' and password == 'password123':
        # 生成JWT
        payload = {
            "user_id": "123",
            "username": username,
            "exp": datetime.datetime.utcnow() + datetime.timedelta(days=1)
        }
        encoded_jwt = jwt.encode(payload, 'my_secret_key', algorithm='HS256')
        return encoded_jwt
    else:
        return None

# 模拟用户登录
jwt_token = login('john_doe', 'password123')
if jwt_token:
    print('Login successful, JWT:', jwt_token)
else:
    print('Login failed')

4.2 实战案例二:简单的信息交换

服务器和客户端之间通过JWT传递信息,确保数据的完整性。

示例代码:

import jwt

# 传递JWT信息
def send_message(jwt_token, message):
    # 模拟信息传递
    if jwt.decode(jwt_token, 'my_secret_key', algorithms=['HS256']):
        print('Message received:', message)
    else:
        print('Invalid token')

# 模拟信息发送
jwt_token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiMTIzIiwidXNlcm5hbWUiOiJqb2huX2RvZSIsImV4cCI6MTY4MDIwMTg5NX0.6wv_NlG55H9jg9B6jZ3iM963FCCYo1sC2v2q172ARj8'
send_message(jwt_token, 'Hello, world!')

4.3 实战案例三:API保护

保护API,确保只有持有有效JWT的用户才能调用API。

示例代码:

import jwt

# API保护
def protected_api(jwt_token):
    try:
        # 验证JWT
        decoded_jwt = jwt.decode(jwt_token, 'my_secret_key', algorithms=['HS256'])
        print('Access granted:', decoded_jwt)
    except jwt.ExpiredSignatureError:
        print('Token expired')
    except jwt.InvalidTokenError:
        print('Invalid token')

# 模拟API调用
jwt_token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiMTIzIiwidXNlcm5hbWUiOiJqb2huX2RvZSIsImV4cCI6MTY4MDIwMTg5NX0.6wv_NlG55H9jg9B6jZ3iM963FCCYo1sC2v2q172ARj8'
protected_api(jwt_token)

5. 常见问题与解决方法

JWT在使用过程中可能会遇到一些常见的问题,以下是一些常见的问题及其解决方法。

5.1 问题一:JWT如何加密

JWT的加密通常涉及以下步骤:

  1. 将header和payload分别编码成base64。
  2. 将编码后的header和payload用.连接起来。
  3. 使用密钥对连接后的字符串进行签名。
  4. 将签名后的字符串附加到header和payload的字符串后面。
  5. 最终的JWT由header、payload和签名三部分组成。

示例代码:

import jwt
import base64

# 自定义生成JWT的函数
def custom_jwt_encode(header, payload, secret):
    base64_header = base64.b64encode(str(header).encode('utf-8')).decode('utf-8')
    base64_payload = base64.b64encode(str(payload).encode('utf-8')).decode('utf-8')
    signature = jwt.sign({**header, **payload}, secret, algorithm='HS256')
    return f'{base64_header}.{base64_payload}.{signature}'

# 示例
header = {"typ": "JWT", "alg": "HS256"}
payload = {"user_id": "123", "username": "john_doe", "exp": 1680201895}
secret = 'my_secret_key'
jwt_token = custom_jwt_encode(header, payload, secret)
print(jwt_token)

5.2 问题二:JWT的安全性如何保证

JWT的安全性主要依赖于以下几点:

  1. 密钥的安全性:JWT的签名使用密钥进行加密,密钥需要严格保密,避免泄露。
  2. 令牌的有效期:设置合理的过期时间,过期后需要重新获取新的JWT。
  3. 令牌的传递:确保JWT在客户端和服务器之间安全传递,可以通过HTTPS等安全协议进行传输。
  4. 令牌的刷新:当JWT过期时,客户端应该能够安全地刷新JWT。
  5. 令牌的验证:服务器在接收到JWT后,需要验证令牌的签名是否有效,以及令牌是否被篡改。

5.3 问题三:JWT与Cookie的区别

JWT与Cookie的主要区别如下:

  • 存储位置:Cookie存储在客户端浏览器上,JWT存储在客户端的内存或本地存储中。
  • 安全性:JWT不依赖于服务器存储会话状态,因此安全性更高;Cookie可能会被窃取或篡改。
  • 跨域支持:JWT天然支持跨域,Cookie需要额外设置withCredentials属性。
  • 传输数据:Cookie可以携带更多的数据,JWT在传输时会受到大小限制。

6. 总结与后续学习资源

6.1 JWT总结

JWT是一种用于在网络应用间安全传输信息的标准。其主要特点包括:

  • 安全性:通过加密签名确保数据的完整性和安全性。
  • 无状态:服务器不需要存储JWT,减轻了服务器的负担。
  • 跨域支持:JWT可以在不同域间传递,支持跨域请求。

6.2 推荐的学习资源

为了更深入地学习JWT,可以参考以下资源:

  • 慕课网提供了多门关于JWT的课程,涵盖基础到高级的各种知识点。
  • JWT官方文档详细介绍了JWT的使用方法及其相关概念。
  • MDN Web Docs提供了丰富的开发资源和示例代码。

6.3 常用的JWT库介绍

以下是几种常用的JWT库,它们提供了方便的接口来生成、验证JWT:

  • PyJWT:Python库,用于生成和验证JWT。

    • 安装:pip install pyjwt
    • 示例代码:
      
      import jwt
    生成JWT

    encoded_jwt = jwt.encode({'user_id': '123', 'username': 'john_doe'}, 'my_secret_key', algorithm='HS256')

    解码JWT

    decoded_jwt = jwt.decode(encoded_jwt, 'my_secret_key', algorithms=['HS256'])
    print(decoded_jwt)

  • jsonwebtoken:Node.js库,用于生成和验证JWT。

    • 安装:npm install jsonwebtoken
    • 示例代码:
      
      const jwt = require('jsonwebtoken');

    // 生成JWT
    const token = jwt.sign({ user_id: '123', username: 'john_doe' }, 'my_secret_key', { expiresIn: '1d' });

    // 解码JWT
    jwt.verify(token, 'my_secret_key', (err, decoded) => {
    if (err) {
    console.log('Invalid token');
    } else {
    console.log('Decoded JWT:', decoded);
    }
    });

  • JWT:PHP库,用于生成和验证JWT。

    • 安装:composer require firebase/php-jwt
    • 示例代码:
      
      require 'vendor/autoload.php';

    use \Firebase\JWT\JWT;

    // 生成JWT
    $token = JWT::encode(['user_id' => '123', 'username' => 'john_doe'], 'my_secret_key');

    // 解码JWT
    try {
    $decoded = JWT::decode($token, 'my_secret_key', ['HS256']);
    print_r($decoded);
    } catch (Exception $e) {
    echo 'Invalid token';
    }

以上资源和库提供了完整的工具链,帮助开发者快速实现JWT相关的功能。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消