Google Cloud Storage 签名的 URL 用于下载面临 CORS 错误

google cloud storage signed url for download facing CORS error

提问人:Parvez Mia 提问时间:11/17/2023 最后编辑:Doug StevensonParvez Mia 更新时间:11/17/2023 访问量:24

问:

我的 react 应用程序向服务器 /signedUrl 发出 POST 请求,以创建一个短暂的签名 URL,该 URL 可用于从 firebase 存储桶中获取文件。 我的服务器配置为允许来自任何来源的请求。对 /signedUrl 的请求将保持挂起状态 10 分钟,之后显示 500 错误并在控制台中打印以下内容:

CORS 策略阻止了从源“https://myclient.web.app”对“https://myserver.com/signedUrl”处的 XMLHttpRequest 的访问:请求的资源上不存在“Access-Control-Allow-Origin”标头。

但是,这在 localhost 中工作正常,但在托管开发和生产环境中失败。我的storageService.ts中还有其他一些函数,例如moveFile(),deleteFile(),deleteDirectory(),它们工作正常。当我在不涉及存储的情况下从 createTemporaryDownloadUrl() 返回 dummyUrl 时,它也可以正常工作。起初我以为它不知何故没有得到它,但它在其他服务功能中也是必需的,而且由于它们运行良好,所以我想这里的情况并非如此。process.env.PROJECT_ID

应用:

const app = express()
  .use(cors({ origin: true }))
  .use(express.json())
  .use(express.urlencoded())
  .use("/signedUrl", signedUrlRouter)

SignedUrlController.ts:

export const signedUrlRouter = express.Router();

signedUrlRouter.post("/", async (request: Request, response: Response): Promise<void> => {

  let fileIdWithPath: string = request.body?.fileIdWithPath || "";

  if (fileIdWithPath === "") throw new Error("Must provide a fileIdWithPath");

  const url = await createTemporaryDownloadUrl(Buckets.ORG, `${fileIdWithPath}`);
  response.status(200).send({ url });
});

StorageService.ts:

import { Storage, GetSignedUrlConfig } from "@google-cloud/storage";

export enum Buckets {
  ORG = ".appspot.com",
  // ... other buckets
}

const storage = new Storage();

const getBucketName = (bucket: Buckets): string => {
  return `${process.env.PROJECT_ID}${bucket}`;
};

export const createTemporaryDownloadUrl = async (bucket: Buckets, fileIdWithPath: string): Promise<string> => {
  const options = {
    version: "v4",
    action: "read",
    expires: Date.now() + 10 * 1000, // 10sec
  } as GetSignedUrlConfig;

  const [url] = await storage.bucket(getBucketName(bucket)).file(fileIdWithPath).getSignedUrl(options);
  return url;
};

存储桶的 CORS 配置:

[
  {
    "origin": ["*"],
    "responseHeader": ["*"],
    "method": ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
    "maxAgeSeconds": 3600
  }
]

存储桶规则:

service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read: if request.auth != null;
      allow write: if false;
    }
  }
}

OPTIONS 常规标头:

Request URL: https://myserver.com/signedUrl
Request Method: OPTIONS
Status Code: 204 No Content
Remote Address: ***.***.***.***:***
Referrer Policy: strict-origin-when-cross-origin

OPTIONS 请求标头:

:authority: dobee-dev.ew.r.appspot.com
:method: OPTIONS
:path: /signedUrl
:scheme: https
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,bn;q=0.8
Access-Control-Request-Headers: authorization,content-type,organizationid
Access-Control-Request-Method: POST
Origin: https://myclient.web.app
Referer: https://myclient.web.app/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Mobile Safari/537.36 Edg/119.0.0.0

OPTIONS 响应标头:

Access-Control-Allow-Headers: authorization,content-type,organizationid
Access-Control-Allow-Methods: GET,HEAD,PUT,PATCH,POST,DELETE
Access-Control-Allow-Origin: https://myclient.web.app
Alt-Svc: h3=":---"; ma=---,h3-29=":---"; ma=---
Content-Length: 0
Content-Type: text/html
Date: Fri, 17 Nov 2023 05:24:43 GMT
Server: Google Frontend
Vary: Origin, Access-Control-Request-Headers
X-Cloud-Trace-Context: ----------
X-Powered-By: Express

POST 常规标头:

Request URL: https://myserver.com/signedUrl
Request Method: POST
Status Code: 500 Internal Server Error
Referrer Policy: strict-origin-when-cross-origin

POST 请求标头:

:authority: myserver.com
:method: POST
:path: /signedUrl
:scheme: https
Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,bn;q=0.8
Authorization: Bearer <token>
Content-Length: 89
Content-Type: application/json
Dnt: 1
Organizationid: <orgID>
Origin: https://myclient.web.app
Referer: https://myclient.web.app/
Sec-Ch-Ua: "Microsoft Edge";v="119", "Chromium";v="119", "Not?A_Brand";v="24"
Sec-Ch-Ua-Mobile: ?1
Sec-Ch-Ua-Platform: "Android"
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Mobile Safari/537.36 Edg/119.0.0.0
node.js firebase express cors google-cloud-storage

评论


答: 暂无答案