React.js集成Transloadit上传图片遇INVALID_SIGNATURE错误求助
解决Uppy集成Transloadit时的INVALID_SIGNATURE错误
在使用Uppy结合Transloadit上传图片时出现INVALID_SIGNATURE错误,核心原因通常是签名生成时的参数与实际发送到Transloadit的参数不匹配,或者签名生成流程存在疏漏。结合你的代码,可按以下步骤排查修复:
1. 确保签名覆盖所有请求参数
Transloadit的签名验证要求签名生成时使用的参数必须与实际发送的所有参数完全一致。你的代码中,fields里的user_id、upload_key等参数会被发送到Transloadit,但签名用的params对象中没有包含这些字段,导致签名验证不通过。
需要将fields参数加入到签名用的params对象中,同时统一插件配置的params与签名参数,避免手动重复编写导致的不一致。
2. 简化签名生成流程
无需额外将JSON字符串转换为Buffer,crypto.update可直接接收UTF-8字符串,简化代码同时避免编码问题。
3. 验证时间格式与环境变量
- 确认
expires生成的格式为YYYY/MM/DD HH:MM:SS+00:00,符合Transloadit要求的RFC 3339格式; - 检查
authSecret、authKey等环境变量是否正确加载,避免出现undefined或空值(可通过控制台打印验证)。
修改后的完整代码
import React from 'react'; import crypto from "crypto" import Uppy from '@uppy/core' import Webcam from '@uppy/webcam' import Transloadit from '@uppy/transloadit'; import Dashboard from '@uppy/react/lib/Dashboard' import '@uppy/dashboard/dist/style.min.css'; import '@uppy/webcam/dist/style.min.css'; const App = () => { const utcDateString = (ms) => { return new Date(ms) .toISOString() .replace(/-/g, '/') .replace(/T/, ' ') .replace(/\.\d+Z$/, '+00:00') } const expiresTime = Date.now() + 1 * 60 * 60 * 1000 const expires = utcDateString(expiresTime) const authKey = process.env.REACT_APP_AUTH_KEY const authSecret = process.env.REACT_APP_AUTH_SECRET const template_id = process.env.REACT_APP_TEMPLATE_ID const user_id = process.env.REACT_APP_USER_ID const upload_key = process.env.REACT_APP_UPLOAD_KEY const notifyUrl = process.env.REACT_APP_NOTIFY_URL // 统一定义所有要发送的参数,包括原fields中的内容 const paramsObj = { auth: { key: authKey, expires, }, template_id, fields: { type: 'avatar', user_id, upload_key, }, } // 转换为无空格压缩的JSON字符串 const params = JSON.stringify(paramsObj) // 生成签名 const signature = `sha384:${crypto.createHmac('sha384', authSecret).update(params).digest('hex')}` const uppy = new Uppy({ autoProceed: false, debug: true }) .use(Webcam) .use(Transloadit, { waitForEncoding: true, alwaysRunAssembly: true, params: paramsObj, // 使用统一的参数对象,避免重复编写 signature, removeFingerprintOnSuccess: true, waitForMetadata: true, notifyUrl, }) .on('transloadit:result', (stepName, result) => { console.log('Results:', stepName, result); }); return ( <> <Dashboard uppy={uppy} /> </> ); }; export default App;
内容的提问来源于stack exchange,提问作者jhonaiker blanco
相关产品推荐
相关产品推荐

