Python JWT — 使用JSON Web令牌保障安全的身份验证

一、什么是JSON Web令牌?

JSON Web令牌(JSON Web Token,JWT)是一种基于JSON的安全传输信息的开放标准,主要用于在网络应用中传递声明,以便于在服务端进行校验,保证数据的安全性和完整性。

一个JWT实际上就是一个字符串,它由三部分组成,分别是头部(header)、负载(payload)和签名(signature)。其中,头部和负载都是JSON格式的数据,在JWT中用Base64Url编码表示。签名则是用于验证消息的完整性的一串字符,由头部、负载、密钥和加密算法共同生成。以下是一个JWT的示例:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

上面的JWT由三部分组成,分别是以.分隔的头部、负载和签名。下面我们将对其进行逐一解析。

1. JWT的头部

JWT的头部主要用于描述关于该JWT的最基本信息,如所使用的加密算法等。头部的格式如下:

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

其中,alg表示签名算法,常用的有HS256、HS384、HS512、RS256、RS384、RS512、ES256、ES384、ES512等。

2. JWT的负载

JWT的负载主要用于存储需要传递的数据,如用户ID、过期时间、权限等信息。负载的格式是一个JSON对象,可以自由地定义自己需要的字段。

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

上面示例中,sub表示用户ID,name表示用户名,iat表示JWT的签发时间。

3. JWT的签名

JWT的签名是用于验证JWT的完整性,防止数据被篡改。签名的生成需要使用一个密钥,对头部和负载进行加密,然后再与密钥一起通过指定的签名算法生成签名。签名的生成示例代码如下:

import base64
import hmac
import hashlib

header = base64.urlsafe_b64encode(b'{"alg": "HS256", "typ": "JWT"}').rstrip(b'=')
payload = base64.urlsafe_b64encode(b'{"sub": "1234567890", "name": "John Doe", "iat": 1516239022}').rstrip(b'=')
secret = 'your-256-bit-secret'

message = header + b'.' + payload
signature = hmac.new(key=secret.encode('utf-8'), msg=message, digestmod=hashlib.sha256).digest()
jwt = message + b'.' + base64.urlsafe_b64encode(signature).rstrip(b'=')

print(jwt.decode('utf-8'))

以上代码主要实现了对于header和payload的base64编码以及签名的生成。其中,b’=’是多余的填充字符,使用rstrip函数进行去除,生成最终的jwt。

二、Python中如何使用JWT实现身份验证?

在使用JWT进行身份验证时,常见的使用方式是把JWT编码后存放在请求的头部,如下所示:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

需要注意的是,Bearer是一种认证机制,用于告知服务器该请求是带有访问令牌的请求。

在Python中,我们可以借助PyJWT库来实现JWT的生成和验证功能。以下是一个使用PyJWT实现JWT身份验证的示例:

import jwt
import datetime
from functools import wraps
from flask import Flask, jsonify, request

app = Flask(__name__)
app.config['SECRET_KEY'] = 'your-secret-key'

def token_required(func):
    @wraps(func)    
    def decorated(*args, **kwargs):        
        token = request.headers.get('Authorization').split(' ')[1]        
        if not token:            
            return jsonify({'message' : 'Token is missing!'}), 401        
        try:            
            data = jwt.decode(token, app.config['SECRET_KEY'], algorithms=["HS256"])            
        except:            
            return jsonify({'message' : 'Token is invalid!'}), 401        
        return func(*args, **kwargs)    
    return decorated

@app.route('/login')
def login():
    auth = request.authorization    
    if auth and auth.password == 'password':        
        token = jwt.encode({'user' : auth.username, 'exp' : datetime.datetime.utcnow() + datetime.timedelta(minutes=30)}, app.config['SECRET_KEY'], algorithm='HS256')        
        return jsonify({'token' : token})
    return make_response('Could not verify!', 401, {'WWW-Authenticate' : 'Basic realm="Login Required"'})

@app.route('/protected')
@token_required
def protected():
    return jsonify({'message' : 'Logged in successfully!'})

if __name__ == '__main__':
    app.run()

上面的代码中,我们使用了一个token_required装饰器,用于验证请求是否带有正确的JWT令牌。在登录时,首先需要进行身份验证,接着生成JWT令牌并返回。在需要进行身份验证的接口中,使用token_required装饰器进行验证,对未授权的请求进行拦截。

三、使用JWT带来的好处

1. 无需存储用户状态

使用JWT进行用户身份验证时,无需在服务器端存储用户的登录状态,从而减轻服务器的负担,提高服务器的性能。

2. 单点登录(SSO)功能

使用JWT进行身份验证时,可以将JWT令牌存储在客户端的Cookie或LocalStorage中,实现跨域单点登录(SSO)的功能。

3. 良好的可扩展性

使用JWT进行身份验证时,负载中可以存储任意的字段信息,可以方便地扩展业务功能,不需要额外修改现有的代码。

四、小结

通过以上介绍,我们了解了JSON Web令牌(JWT)是一种基于JSON的安全传输信息的开放标准,可以在网络应用中实现用户身份验证的功能。在Python中,我们可以通过PyJWT库来实现JWT的生成和验证。使用JWT带来的好处包括无需存储用户状态、单点登录(SSO)功能和良好的可扩展性。

原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/155507.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
小蓝小蓝
上一篇 2024-11-17 02:41
下一篇 2024-11-17 02:41

相关推荐

  • Git secbit:一种新型的安全Git版本

    Git secbit是一种新型的安全Git版本,它在保持Git原有功能的同时,针对Git存在的安全漏洞做出了很大的改进。下面我们将从多个方面对Git secbit做详细地阐述。 一…

    编程 2025-04-29
  • JWT验证Token的实现

    本文将从以下几个方面对JWT验证Token进行详细的阐述,包括:JWT概述、JWT验证Token的意义、JWT验证Token的过程、JWT验证Token的代码实现、JWT验证Tok…

    编程 2025-04-29
  • 手机安全模式怎么解除?

    安全模式是一种手机自身的保护模式,它会禁用第三方应用程序并使用仅限基本系统功能。但有时候,安全模式会使你无法使用手机上的一些重要功能。如果你想解除手机安全模式,可以尝试以下方法: …

    编程 2025-04-28
  • Powersploit:安全评估与渗透测试的利器

    本文将重点介绍Powersploit,并给出相关的完整的代码示例,帮助安全人员更好地运用Powersploit进行安全评估和渗透测试。 一、Powersploit简介 Powers…

    编程 2025-04-28
  • jiia password – 保护您的密码安全

    你是否曾经遇到过忘记密码、密码泄露等问题?jiia password 正是一款为此而生的解决方案。本文将从加密方案、密码管理、多平台支持等多个方面,为您详细阐述 jiia pass…

    编程 2025-04-27
  • JWT String Argument Cannot Be Null or Empty

    JWT(JSON Web Token)是一种用于进行身份验证的标准。在使用JWT时,经常会遇到“JWT String Argument Cannot Be Null or Empt…

    编程 2025-04-27
  • Rappor——谷歌推出的安全数据收集方案

    Rappor是一种隐私保护技术,可以在保持用户私密信息的前提下,收集用户的随机信号数据。它可以用于应对广泛的数据收集需求,让用户在参与数据收集的过程中感到安全和安心。 一、Rapp…

    编程 2025-04-27
  • Isolates:高效、安全、可靠的并发执行体系

    如果你想快速编写高性能、可靠、安全的并发应用程序,那么,你一定不能错过Dart编程语言中的一个重要特性:Isolates。 一、什么是Isolates? Isolates是Dart…

    编程 2025-04-25
  • gitssl——保护您的git仓库安全

    一、什么是gitssl 1、gitssl是一种保护git仓库安全的方法 2、gitssl能够通过SSL证书来保护git数据传输过程中的安全性 3、gitssl使用方便,只需要简单的…

    编程 2025-04-24
  • Java DelayQueue:实现延迟任务的线程安全队列

    一、DelayQueue的概述 Java的DelayQueue 是一个阻塞队列队列,主要用来实现对延迟任务的调度,也就是在指定的时间之后才能够取出任务来执行。该队列中保存的元素都必…

    编程 2025-04-23

发表回复

登录后才能评论