导读:本期聚焦于小伙伴创作的《Python Flask如何保护API接口?通过API Key与签名验证防篡改的方法是什么》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《Python Flask如何保护API接口?通过API Key与签名验证防篡改的方法是什么》有用,将其分享出去将是对创作者最好的鼓励。

Flask API接口的安全风险

当Flask开发的API接口直接暴露给外部使用时,可能会遇到未授权调用、参数被中途修改、重复请求攻击等问题,这些问题会导致服务资源被滥用或者业务数据出现异常。通过API Key校验调用权限,结合签名验证确认参数未被篡改,是常用的轻量级防护方案。

API Key与签名验证的核心逻辑

API Key的作用

API Key是分配给合法调用方的身份标识,每个调用方持有唯一的Key,服务端通过校验请求中携带的Key判断调用方是否有权限访问接口。API Key通常不会直接用于防篡改,只做身份识别。

签名验证的作用

签名是对请求参数按照固定规则拼接、加密后生成的字符串,服务端用同样的规则对参数重新计算签名,与请求携带的签名对比,一致则说明参数未被修改。同时可以加入时间戳、随机字符串等参数,防止重放攻击。

完整实现步骤

1. 分配API Key与密钥

提前给每个调用方分配唯一的api_key和对应的secret_keysecret_key仅调用方和服务端知晓,用于生成签名,不随请求传输。

2. 定义签名生成规则

签名生成需要固定步骤,避免规则混乱导致校验失败:

  • 收集所有请求参数,排除签名本身参数
  • 按照参数名的字典序排序
  • 拼接成参数名=参数值的字符串,用&连接
  • 在拼接字符串末尾追加secret_key
  • 对拼接后的字符串做MD5加密,生成签名

3. 服务端校验逻辑实现

首先编写工具函数处理签名生成和校验:

import hashlib
import time
import json

# 模拟存储api_key和对应的secret_key,实际项目可存数据库或配置中心
API_KEY_MAP = {
    "test_api_key_123": "test_secret_key_456"
}

def generate_sign(params, secret_key):
    """生成签名"""
    # 排除sign参数本身
    params_copy = {k: v for k, v in params.items() if k != "sign"}
    # 按参数名字典序排序
    sorted_params = sorted(params_copy.items(), key=lambda x: x[0])
    # 拼接参数字符串
    param_str = "&".join([f"{k}={v}" for k, v in sorted_params])
    # 追加secret_key
    sign_str = param_str + secret_key
    # MD5加密,生成小写签名
    sign = hashlib.md5(sign_str.encode("utf-8")).hexdigest()
    return sign

def verify_request(params):
    """校验请求合法性,返回校验结果和错误信息"""
    # 1. 校验api_key是否存在
    api_key = params.get("api_key")
    if not api_key or api_key not in API_KEY_MAP:
        return False, "无效的api_key"
    # 2. 校验签名是否存在
    request_sign = params.get("sign")
    if not request_sign:
        return False, "缺少签名参数"
    # 3. 校验时间戳,防止重放攻击,允许10秒误差
    timestamp = params.get("timestamp")
    if not timestamp:
        return False, "缺少时间戳参数"
    try:
        timestamp = int(timestamp)
    except ValueError:
        return False, "时间戳格式错误"
    if abs(int(time.time()) - timestamp) > 10:
        return False, "请求已过期"
    # 4. 重新计算签名并对比
    secret_key = API_KEY_MAP.get(api_key)
    server_sign = generate_sign(params, secret_key)
    if server_sign != request_sign:
        return False, "签名校验失败"
    return True, "校验通过"

4. Flask接口编写

编写一个需要保护的示例接口,在接口中先执行校验逻辑,通过后再处理业务:

from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route("/api/get_user_info", methods=["GET"])
def get_user_info():
    # 获取所有请求参数
    params = request.args.to_dict()
    # 校验请求合法性
    is_valid, msg = verify_request(params)
    if not is_valid:
        return jsonify({"code": 401, "msg": msg}), 401
    # 校验通过,处理业务逻辑,这里模拟返回用户信息
    user_id = params.get("user_id")
    return jsonify({
        "code": 200,
        "msg": "请求成功",
        "data": {
            "user_id": user_id,
            "user_name": "测试用户",
            "age": 25
        }
    })

if __name__ == "__main__":
    app.run(debug=True, host="127.0.0.1", port=5000)

5. 调用方请求示例

调用方需要按照同样的规则生成签名,再发起请求,以下是调用方的示例代码:

import hashlib
import time
import requests

API_KEY = "test_api_key_123"
SECRET_KEY = "test_secret_key_456"
API_URL = "http://127.0.0.1:5000/api/get_user_info"

def call_api(user_id):
    # 构造请求参数
    params = {
        "api_key": API_KEY,
        "user_id": user_id,
        "timestamp": str(int(time.time()))
    }
    # 生成签名
    params["sign"] = generate_sign(params, SECRET_KEY)
    # 发起请求
    response = requests.get(API_URL, params=params)
    print(response.json())

if __name__ == "__main__":
    call_api("1001")

注意事项

  • secret_key需要妥善保管,不能泄露给第三方,定期可以更换密钥提升安全性
  • 时间戳的误差范围可以根据业务场景调整,对安全性要求高的场景可以缩短误差时间
  • 如果接口支持POST请求,需要将请求体参数也纳入签名计算范围,规则与GET参数一致
  • 实际生产环境中,API Key的分配、权限管理可以结合数据库或专业的API网关实现,更方便管理
签名验证可以有效防止参数篡改,但不能完全替代HTTPS,建议生产环境同时开启HTTPS,避免请求内容在传输过程中被明文窃取。

FlaskAPI_Key签名验证接口防篡改修改时间:2026-06-26 16:15:40

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。