NodeJS 尝试通过云CDN访问GCP存储桶内容时获取`signed_request_invalid_format`

eh57zj3b  于 2023-04-29  发布在  Node.js
关注(0)|答案(1)|浏览(84)

我正在使用签名Cookie,通过Cloud CDN访问GCP存储桶中的一些受限文件。我正在使用以下函数对cookie进行签名:

signCookie(urlPrefix: string, keyName: string, key: string, expires: number) {
    // Base64url encode the url prefix
    const urlPrefixEncoded = Buffer.from(urlPrefix).toString('base64url');

    // Input to be signed
    const input = `URLPrefix=${urlPrefixEncoded}:Expires=${expires}:KeyName=${keyName}`;

    // Create bytes from given key string.
    const keyBytes = Buffer.from(key, 'base64');

    // Use key bytes and crypto.createHmac to produce a base64 encoded signature which is then escaped to be base64url encoded.
    const signature = createHmac('sha1', keyBytes).update(input).digest('base64url');

    // Adding the signature on the end if the cookie value
    const signedValue = `${input}:Signature=${signature}`;

    return signedValue;
  }

Cookie正在生成并发送到CDN,但它失败,状态为403,并出现以下消息:

Error: Forbidden
Your client does not have permission to get URL ********/sample.pdf from this server.

在检查负载均衡器日志时,我得到这个statusDetails: "signed_request_invalid_format"。不幸的是,此消息不存在于此处列出的错误消息列表中。有人能帮我指出这个问题吗?签名的cookie无效吗?Cookie生成逻辑中是否存在错误?

cdmah0mi

cdmah0mi1#

这个答案是针对使用express作为服务器的用户的。sign cookie函数按预期生成cookie,设置cookie时出现问题。当我们这样设置cookie时:

response.cookie('Cloud-CDN-Cookie', cookieValue, {
          httpOnly: true,
          expires: new Date(cookieExpiryTime),
});

cookie值被URI编码,因此URL的所有保留字符(如=)都被替换为%3D,依此类推。这会破坏cookie结构,如文档中所述:

URLPrefix=$BASE64URLECNODEDURLORPREFIX:Expires=$TIMESTAMP:KeyName=$KEYNAME:Signature=$BASE64URLENCODEDHMAC

要修复此问题,请在设置cookie时传递一个额外的encode函数:

response.cookie('Cloud-CDN-Cookie', cookieValue, {
          httpOnly: true,
          expires: new Date(cookieExpiryTime),
          encode: val => val
});

希望它能保存你的时间。

相关问题