【问题标题】:Cloudinary Signed Uploads with Widget带有小部件的 Cloudinary 签名上传
【发布时间】:2020-04-11 16:58:03
【问题描述】:

文档非常令人沮丧。

我正在使用上传小部件来尝试允许用户为他们的个人资料上传多张图片。我不能使用未签名的上传,因为可能会被滥用。

我宁愿通过上传小部件而不是通过服务器上传文件,因为它似乎应该如此简单

我已经拼凑了我认为应该起作用的东西,但它仍然在说:Upload preset must be whitelisted for unsigned uploads

服务器:

// grab a current UNIX timestamp
const millisecondsToSeconds = 1000;
const timestamp = Math.round(Date.now() / millisecondsToSeconds);
// generate the signature using the current timestmap and any other desired Cloudinary params
const signature = cloudinaryV2.utils.api_sign_request({ timestamp }, CLOUDINARY_SECRET_KEY);
// craft a signature payload to send to the client (timestamp and signature required)
return signature;

也试过

return {
  signature,
  timestamp,
};

也试过

const signature = cloudinaryV2.utils.api_sign_request(
      data.params_to_sign,
      CLOUDINARY_SECRET_KEY,
    );

客户:

const generateSignature = async (callback: Function, params_to_sign: object): Promise<void> => {
  try {
    const signature = await generateSignatureCF({ slug: 'xxxx' }); 
  // also tried { slug: 'xxxx', params_to_sign }
    callback(signature);
  } catch (err) {
    console.log(err);
  }
};
cloudinary.openUploadWidget(
  {
    cloudName: 'xxx',
    uploadPreset: 'xxxx',
    sources: ['local', 'url', 'facebook', 'dropbox', 'google_photos'],
    folder: 'xxxx',
    apiKey: ENV.CLOUDINARY_PUBLIC_KEY,
    uploadSignature: generateSignature,
  },
  function(error, result) {
    console.log(error);
  },
);

【问题讨论】:

    标签: javascript node.js upload cloudinary


    【解决方案1】:

    让我们都花点时间指出 Cloudinary 的文档是多么可怕。这很容易是我见过的最糟糕的。噩梦燃料。

    现在我已经摆脱了这种想法......我真的需要能够做到这一点,而且我花了太长时间将头撞在墙上,这本来应该非常简单。在这里……

    服务器(Node.js)

    您需要一个向前端返回签名-时间戳对的端点:

    import cloudinary from 'cloudinary'
    
    export async function createImageUpload() {
      const timestamp = new Date().getTime()
      const signature = await cloudinary.utils.api_sign_request(
        {
          timestamp,
        },
        process.env.CLOUDINARY_SECRET
      )
      return { timestamp, signature }
    }
    

    客户端(浏览器)

    客户端向服务器请求签名-时间戳对,然后使用它上传文件。示例中使用的文件应来自 &lt;input type='file'/&gt; 更改事件等。

    const CLOUD_NAME = process.env.CLOUDINARY_CLOUD_NAME
    const API_KEY = process.env.CLOUDINARY_API_KEY
    
    async function uploadImage(file) {
      const { signature, timestamp } = await api.post('/image-upload')
      const form = new FormData()
      form.append('file', file)
      const res = await fetch(
        `https://api.cloudinary.com/v1_1/${CLOUD_NAME}/image/upload?api_key=${API_KEY}&timestamp=${timestamp}&signature=${signature}`,
        {
          method: 'POST',
          body: form,
        }
      )
      const data = await res.json()
      return data.secure_url
    }
    

    就是这样。这就是它所需要的。如果只有 Cloudinary 在他们的文档中有这个。

    【讨论】:

      【解决方案2】:

      男人。我讨厌我的生活。我终于弄明白了。我确实花了我美化上传小部件 js 来理解函数的返回应该是一个字符串而不是一个对象,即使文档看起来不是这样。

      这里是如何使用 Firebase 云函数实现签名上传

      import * as functions from 'firebase-functions';
      import cloudinary from 'cloudinary';
      const CLOUDINARY_SECRET_KEY = functions.config().cloudinary.key;
      const cloudinaryV2 = cloudinary.v2;
      module.exports.main = functions.https.onCall(async (data, context: CallableContext) => {
        // Checking that the user is authenticated.
        if (!context.auth) {
          // Throwing an HttpsError so that the client gets the error details.
          throw new functions.https.HttpsError(
            'failed-precondition',
            'The function must be called while authenticated.',
          );
        }
        try {
          return cloudinaryV2.utils.api_sign_request(data.params_to_sign, CLOUDINARY_SECRET_KEY);
        } catch (error) {
          throw new functions.https.HttpsError('failed-precondition', error.message);
        }
      });
      
      
      // CLIENT
      const uploadWidget = () => {
        const generateSignature = async (callback: Function, params_to_sign: object): Promise<void> => {
          try {
            const signature = await generateImageUploadSignatureCF({ params_to_sign });
            callback(signature.data);
          } catch (err) {
            console.log(err);
          }
        };
      
        cloudinary.openUploadWidget(
          {
            cloudName: 'xxxxxx',
            uploadSignature: generateSignature,
            apiKey: ENV.CLOUDINARY_PUBLIC_KEY,
          },
          function(error, result) {
            console.log(error);
          },
        );
      };
      

      【讨论】:

        猜你喜欢
        • 2015-02-28
        • 2017-01-27
        • 1970-01-01
        • 2017-05-10
        • 2019-01-23
        • 2019-05-25
        • 2014-09-27
        • 2018-08-01
        • 2019-12-14
        相关资源
        最近更新 更多