📜  python api 定义不记名令牌 - Python (1)

📅  最后修改于: 2023-12-03 15:33:58.131000             🧑  作者: Mango

Python API 定义不记名令牌

在web开发中,用户鉴权是一个非常重要的点。例如,用户登录后每次请求都需要携带Token,服务器需要校验Token以确定用户的身份。那么如何生成和校验这些Token呢?

在这篇文章中,我们将介绍如何使用Python实现不记名令牌,并通过一个简单的例子来演示。

定义不记名令牌

不记名令牌是一种简单的基于消息摘要算法的Token,Token中存储了一些相关信息的哈希值,确保信息不被窃取或篡改。

以下是不记名令牌的一个简单实现,我们将使用Python的HMAC模块计算哈希值:

import hmac
import hashlib
import base64

def generate_token(secret_key: str, message: str) -> str:
    h = hmac.new(secret_key.encode('utf-8'), message.encode('utf-8'), hashlib.sha256)
    return base64.urlsafe_b64encode(h.digest()).decode('utf-8')

def verify_token(secret_key: str, message: str, token: str) -> bool:
    return token == generate_token(secret_key, message)

这里我们使用了hmac.new()函数来计算哈希值,它需要传入一个秘钥和消息,以及一个哈希函数。接着我们对哈希值使用base64.urlsafe_b64encode()进行编码,以便转换为字符串方便传输。最后我们还加入了一个校验Token的函数verify_token(),用于对比当前计算的Token与原有Token是否相同。

例子演示

接下来我们将使用Flask Web框架来演示不记名Token的生成和校验。首先安装Flask:

pip install flask

接着创建一个名为'server.py'的文件,代码如下:

from flask import Flask, request, jsonify
import hmac
import hashlib
import base64

app = Flask(__name__)
SECRET_KEY = 'MySecretKey'

def generate_token(secret_key: str, message: str) -> str:
    h = hmac.new(secret_key.encode('utf-8'), message.encode('utf-8'), hashlib.sha256)
    return base64.urlsafe_b64encode(h.digest()).decode('utf-8')

def verify_token(secret_key: str, message: str, token: str) -> bool:
    return token == generate_token(secret_key, message)

@app.route('/api/login', methods=['POST'])
def login():
    username = request.json.get('username')
    password = request.json.get('password')
    if username == 'admin' and password == 'password':
        message = username + password + SECRET_KEY
        token = generate_token(SECRET_KEY, message)
        return jsonify({'token': token})
    return jsonify({'error': 'Invalid credentials'})

@app.route('/api/data', methods=['POST'])
def data():
    data = request.json
    token = request.headers.get('Authorization')
    if token and verify_token(SECRET_KEY, str(data), token):
        return jsonify({'message': 'Success'})
    return jsonify({'error': 'Invalid Token'})

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

这段代码中包含两个路由,'/api/login'用于用户登录,成功后生成Token,将Token以JSON格式返回;'/api/data'用于用户请求数据,需要校验Token是否有效。

我们可以使用curl来测试这段代码:

curl -H "Content-Type: application/json" -X POST -d '{"username":"admin", "password":"password"}' http://127.0.0.1:5000/api/login

返回的结果如下:

{
    "token": "ez8NpOzjKkNl_9BxRfopGfrDfsgeus2jrtZaHVP0YCQ"
}

接着我们将Token携带在请求头Authorization中发起请求:

curl -H "Content-Type: application/json" -H "Authorization: ez8NpOzjKkNl_9BxRfopGfrDfsgeus2jrtZaHVP0YCQ" -X POST -d '{"data":"This is a test"}' http://127.0.0.1:5000/api/data

返回的结果为:

{
    "message": "Success"
}

这说明Token校验成功,请求被正确处理。

通过上述演示,我们可以看到不记名令牌是一种非常简洁和实用的鉴权方法。在web应用程序中广泛使用,确保数据的机密性和完整性。在Python中,我们可以通过简单的HMAC算法实现Token的生成和校验,保证了应用程序的安全性。