后端数据可视化运维【免费下载链接】TautulliA Python based monitoring and tracking tool for Plex Media Server.项目地址https://gitcode.com/gh_mirrors/ta/Tautulli点击查看免费下载导读本文讲解 Cloudinary 的签名浏览器直传模式由你的服务器为上传参数签发签名浏览器或移动端客户端携带该签名把文件直接 POST 到api.cloudinary.com文件不经由你的应用服务器而api_secret也始终不出服务器。Tautulli 仓库在 lib/cloudinary 目录下完整打包了 Cloudinary Python SDK含本主题对应的官方文档与全部实现源码文章将结合该 SDK 的 utils.py、uploader.py、api.py 源码从签名算法、端点构造、上传预置preset到响应校验与排错给你一套可直接落地的直传方案。适用场景什么时候需要签名直传常规的服务端上传cloudinary.uploader.upload(...)是文件先到你的应用、再由应用转发给 Cloudinary而浏览器直传解决的是另一类需求文件不经过你的应用服务器直接由浏览器/移动端上传到 Cloudinary节省服务器带宽与中转时间但上传授权由你的服务器控制——api_secret只存在于服务器端永不随请求下发到客户端。实现方式即本文主题服务器为一批上传参数如timestamp、folder计算签名客户端将文件 这批参数 签名一起 POST 给 Cloudinary。若你不需要此模式服务端上传请参阅 Upload an image在 Django 中还可以使用CloudinaryJsFileField直接渲染一个已签名的直传组件见 Use with Django。完整流程从签名端点到客户端上传第一步服务器签发签名参数签名由服务器端完成。核心思路是把所有将要随上传发送给 Cloudinary 的参数收集起来连同当前 Unix 时间戳一起签名。下面的示例代码与官方文档一致直接可以运行import time import cloudinary import cloudinary.utils # 导入 cloudinary 之后即自动可用 # 配置自动从 CLOUDINARY_URL 环境变量读取 def signature_payload(): config cloudinary.config() # 这里签名的每一个参数客户端都必须原样逐字节提交 params_to_sign { timestamp: int(time.time()), folder: user-uploads, } signature cloudinary.utils.api_sign_request(params_to_sign, config.api_secret) return { signature: signature, # 40 位十六进制字符串SHA-1 api_key: config.api_key, # 公开信息可以安全下发 cloud_name: config.cloud_name, **params_to_sign, } if __name__ __main__: print(signature_payload())几点关键说明api_key与cloud_name是公开信息随载荷一起返回给客户端无安全风险只有api_secret不能离开服务器。签名结果默认是 SHA-1 的 40 位十六进制串若配置了signature_algorithmsha256则为 64 位十六进制串。cloudinary.config()返回的是进程级全局配置对象。SDK 在首次使用时自动从CLOUDINARY_URL形如cloudinary://api_key:api_secretcloud_name解析出cloud_name、api_key、api_secret解析逻辑见 lib/cloudinary/init.py也可调用cloudinary.config(cloud_name..., api_key..., api_secret...)显式配置。第二步客户端 POST 到上传端点客户端拿到上述载荷后向如下端点发起 POSThttps://api.cloudinary.com/v1_1/cloud_name/image/upload请求包含签名过的全部参数timestamp、folderfileapi_keysignature。不要手写这个 URL而应调用 SDK 动态构建避免 cloud name 变化或版本前缀调整时失效endpoint cloudinary.utils.cloudinary_api_url(upload, resource_typeimage) # 结果形如 https://api.cloudinary.com/v1_1/cloud/image/upload源码佐证cloudinary_api_url的实现位于 lib/cloudinary/utils.py它最终调用base_api_urlutils.py由upload_prefix默认https://api.cloudinary.com、API_VERSION即v1_1定义于 lib/cloudinary/init.py和cloud_name拼装而成缺cloud_name时直接抛出ValueError(Must supply cloud_name)。签名算法底层原理源码级解析理解api_sign_request的内部实现对排查签名失败至关重要。其定义在 lib/cloudinary/utils.py签名流程如下组装待签字符串调用api_string_to_signutils.py对参数字典做规范化列表值用,连接如tags[a,b]→tagsa,b布尔值转为小写字符串True→true空值None或直接跳过、不参与签名每个键值对格式化为keyvalue按参数名排序后用连接成key1value1key2value2形式的字符串。拼接api_secret并哈希compute_hex_hash(to_sign api_secret, algorithm)utils.py对待签字符串 api_secret计算哈希默认算法是sha1常量定义于 utils.py。签名版本差异signature_version默认取配置值2见 lib/cloudinary/init.py。版本 2 会对每个keyvalue中的做百分号编码替换为%26见_encode_paramutils.py用于防止参数走私parameter smuggling版本 1 不做编码仅用于向后兼容如响应签名校验见后文。这也解释了官方文档中的一条排错线索当 Cloudinary 返回Invalid Signature hash. String to sign - params时错误信息里打印的正是服务端实际参与签名的规范化字符串——把它与客户端实际提交的参数逐一比对几乎总能发现是多签或漏签了一个参数而不是密钥配错。最容易导致失败的一条规则签名参数与提交参数必须完全一致。如果客户端额外加了一个服务器没签过的tags或者服务器签了folder而客户端没发Cloudinary 都会返回Invalid Signature。原则是客户端将要发送的每一个参数都必须被服务器签名客户端不要发送任何未被签名的额外参数。另外签名与时间戳绑定有效期为一小时。因此正确的做法是每次上传签发一次签名不要缓存签名复用在多个上传上。源码印证服务端 SDK 自身在上传时会通过sign_requestutils.py把参数清理cleanup_params过滤空值后统一签名并顺带写入signature与api_key其中non_signable指定的键会照常发送但被排除在签名之外。可见签什么就发什么是整个 SDK 与 Cloudinary 服务端的共同约定。用上传预置Upload Preset限制客户端行为签名只代表这个上传是经过授权的它本身不限制客户端能传什么。要约束格式、大小或目标目录应当签发一个签名预置signed preset而不是签发裸参数params_to_sign {timestamp: int(time.time()), upload_preset: user-avatars}预置只需在管理端创建一次把目标文件夹、allowed_formats和所需的转换transformation固化进去import cloudinary.api cloudinary.api.create_upload_preset( nameuser-avatars, unsignedFalse, folderavatars, allowed_formatsjpg,png,webp, transformation[{width: 512, height: 512, crop: fill, gravity: face}], )该例中的预置会把用户头像统一裁剪为 512×512、以人脸为重心填充gravity: face且只接受 jpg/png/webp杜绝了客户端自定义上传目标或格式的余地。源码佐证create_upload_preset是 Admin API 的封装实现在 lib/cloudinary/api.py通过POST upload_presets创建支持unsigned、disallow_public_id、name、live等选项unsignedFalse即为签名预置。无签名上传Unsigned Upload彻底放弃控制如果使用unsignedTrue的预置客户端上传时连签名都不需要——服务器往返彻底消失但同时你也失去了对谁能上传的控制。因此无签名模式只应服务于真正公开的上传场景并配合一个刻意收紧的预置固定 folder、allowed_formats、以及大小上限。服务端 SDK 对应的调用是cloudinary.uploader.unsigned_uploadcloudinary.uploader.unsigned_upload(photo.jpg, public-drop-box)源码佐证unsigned_upload定义于 lib/cloudinary/uploader.py其本质是调用upload(file, upload_presetupload_preset, unsignedTrue, **options)——在call_apiuploader.py中unsignedTrue会跳过utils.sign_request签名步骤见 uploader.py仅依赖预置本身的约束。校验返回结果信任来自 Cloudinary 的响应浏览器直传之后你的服务器可能收到来自 Cloudinary 的响应和webhook 通知。由于它们可能经过不可信网络SDK 提供了对应的签名校验工具确保其确实来自 Cloudinarycloudinary.utils.verify_api_response_signature( result[public_id], result[version], result[signature] )对于 webhook 负载则使用cloudinary.utils.verify_notification_signature(body, timestamp, signature)源码佐证verify_api_response_signatureutils.py对public_id与version两个字段按签名版本 1重新计算签名并比对版本 1 用于向后兼容CloudinaryResource.validate()方法lib/cloudinary/init.py正是调用它来做对象级校验。verify_notification_signatureutils.py计算body timestamp api_secret的哈希并与签名比对且默认valid_for7200秒2 小时——超过该窗口的timestamp直接返回False防止重放攻击。注意此处的 2 小时是针对 webhook 通知的时效上传签名的一小时时效由 Cloudinary 服务端执行。疑难排查清单Invalid Signature hash. String to sign - params—— 签名参数与提交参数不一致。错误信息打印了服务端实际签名的字符串与客户端发送的内容逐项比对即可定位。这几乎总是多一个参数或漏一个参数导致而非密钥错误。Must supply api_secret—— 签名流程缺少凭据配置。只配置了cloud_name通常足够生成 URL但上传签名与 Admin API 都需要api_secret请重新从控制台复制完整的三元组cloud_name、api_key、api_secret。Stale request——timestamp超过一小时或服务器时钟不准。检查服务器时间同步并在每次上传时重新签发。Upload preset not found—— 该预置名在当前的 cloud 中不存在或预置是unsignedTrue而你在对请求做签名反之亦然。客户端报 CORS 错误—— 上传地址发错了主机。浏览器直传必须发往api.cloudinary.com而不是用于交付图片的res.cloudinary.com。若问题源于基础配置例如Must supply cloud_name / api_key或Invalid CLOUDINARY_URL scheme可进一步参阅配置文档 configure-cloudinary.md 中的排查小节——该文档还明确指出一旦设置了任一CLOUDINARY_*独立环境变量SDK 会优先读取它们并完全忽略CLOUDINARY_URL两种配置风格不要混用。相关文档Upload an image —— 服务端直传方式。Use with Django ——CloudinaryJsFileField为你渲染一个已签名的浏览器直传组件。configure-cloudinary.md ——CLOUDINARY_URL等基础配置与常见配置错误排查。Cloudinary 官方还提供完整的浏览器内上传 UIUpload Widget其消费的正是本文所述的签名协议签名生成的完整参数规则可参考 Cloudinary 官方签名生成文档signatures.md。赞分享后端数据可视化运维【免费下载链接】TautulliA Python based monitoring and tracking tool for Plex Media Server.项目地址https://gitcode.com/gh_mirrors/ta/Tautulli点击查看免费下载相关推荐Supabase Storage 签名可续传上传Signed Resumable Upload基于 Uppy TUS 与 createSignedUploadUrl 的完整实战Supabase Storage 签名可续传上传Signed Resumable Upload基于 Uppy TUS 与 createSignedUp后端前端数据库Teleport tsh 浏览器 MFABrowser MFA完整指南原理、流程、配置与源码实现Teleport tsh 浏览器 MFABrowser MFA完整指南原理、流程、配置与源码实现 浏览器 MFABrowser MFA是 Telepo网络安全认证鉴权运维后端Crawl4AI 内置浏览器Builtin Browser实战指南browser_modebuiltin 与 crwl browser 全解析Crawl4AI 内置浏览器Builtin Browser实战指南browser_modebuiltin 与 crwl browser 全解析 本文网页爬虫RAG人工智能AI 应用创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
阅读完成 · 觉得有帮助?