使用节点js创建预签名网址并将文件上传到Google云端存储

时间:2016-03-15 06:05:14

标签: javascript node.js google-cloud-storage

我需要使用签名网址将文件上传到谷歌云存储。我需要通过不同的步骤上传。

  1. 使用bucketName,服务密钥和所需的安全凭证创建signedUrl。(使用任何node.js库)

  2. 使用Postman或restClient上传包含已创建签名网址的单个文件。

  3. 这是我创建用于上传的signedUrl的代码

    var crypto = require("crypto");
    var fs = require("fs");
    
    var URL_VALID_DURATION = 1000 * 120;//for 120 seconds
    
    var expiry = Math.floor(((new Date).getTime() + URL_VALID_DURATION) / 1000);
    
    var key = 'filename';
    var bucketName = 'bucketName';
    var accessId = 'gserviceaccount.com';
    var stringPolicy = "POST\n" + "\n" + "\n" + expiry + "\n" + '/' + bucketName + '/' + key;
    var base64Policy = Buffer(stringPolicy, "utf-8").toString("base64");
    var privateKey = fs.readFileSync("google-services-private-key.pem", "utf8");
    var signature = encodeURIComponent(crypto.createSign('sha256').update(stringPolicy).sign(privateKey, "base64"));
    var signedUrl = "https://" + bucketName + ".commondatastorage.googleapis.com/" + key + "?GoogleAccessId=" + accessId + "&Expires=" + expiry + "&Signature=" + signature;
    
    console.log(signedUrl);
    

    但是在使用邮递员或休息客户端时我得到了错误

    <?xml version='1.0' encoding='UTF-8'?>
    <Error>
        <Code>SignatureDoesNotMatch</Code>
        <Message>The request signature we calculated does not match the signature you provided. Check your Google secret key and signing method.</Message>
        <StringToSign>PUT
    
    multipart/form-data
    1458024549
    /bucketName/fileName</StringToSign>
    </Error>
    

1 个答案:

答案 0 :(得分:3)

刚刚将stringPolicy方法更改为PUT。并以二进制形式发送图像。

var crypto = require("crypto");
var fs = require("fs");

var URL_VALID_DURATION = 1000 * 120;//for 120 seconds

var expiry = Math.floor(((new Date).getTime() + URL_VALID_DURATION) / 1000);

var key = 'filename';
var bucketName = 'bucketName';
var accessId = 'gserviceaccount.com';
var stringPolicy = "PUT\n" + "\n" + "\n" + expiry + "\n" + '/' + bucketName + '/' + key;
var base64Policy = Buffer(stringPolicy, "utf-8").toString("base64");
var privateKey = fs.readFileSync("google-services-private-key.pem", "utf8");
var signature = encodeURIComponent(crypto.createSign('sha256').update(stringPolicy).sign(privateKey, "base64"));
var signedUrl = "https://" + bucketName + ".commondatastorage.googleapis.com/" + key + "?GoogleAccessId=" + accessId + "&Expires=" + expiry + "&Signature=" + signature;

console.log(signedUrl);