构建应用用户档案照片组件。我设置了一个没有公共访问权限的Google Cloud存储桶,使用细粒度ACL,以及一个具有存储管理员角色的服务帐户。我下载了JSON密钥,放在根目录中package.json旁边,并在我的文件上传/下载控制器中引用:
const processFile = require("../middleware/upload");
const { format } = require("util");
const { Storage } = require("@google-cloud/storage");
const storage = new Storage({ keyFilename: "my-service-account.json" });
const bucket = storage.bucket("my-gcp-storage-bucket");
const upload = async (req, res) => {
try {
await processFile(req, res);
if (!req.file) {
return res.status(400).send({ message: "Please upload a file!" });
}
const blob = bucket.file(req.file.originalname);
const blobStream = blob.createWriteStream({
resumable: false,
});
blobStream.on("error", (err) => {
res.status(500).send({ message: err.message });
});
blobStream.on("finish", async (data) => {
const publicUrl = format(
`https://storage.googleapis.com/${bucket.name}/${blob.name}`
);
try {
await bucket.file(req.file.originalname).makePublic();
} catch {
return res.status(500).send({
message:
`Uploaded the file successfully: ${req.file.originalname}, but public access is denied!`,
url: publicUrl,
});
}
res.status(200).send({
message: "Uploaded the file successfully: " + req.file.originalname,
url: publicUrl,
});
});
blobStream.end(req.file.buffer);
} catch (err) {
console.log(err);
if (err.code == "LIMIT_FILE_SIZE") {
return res.status(500).send({
message: "File size cannot be larger than 2MB!",
});
}
res.status(500).send({
message: `Could not upload the file: ${req.file.originalname}. ${err}`,
});
}
};
const getListFiles = async (req, res) => {
try {
const [files] = await bucket.getFiles();
let fileInfos = [];
files.forEach((file) => {
fileInfos.push({
name: file.name,
url: file.metadata.mediaLink,
});
});
res.status(200).send(fileInfos);
} catch (err) {
console.log(err);
res.status(500).send({
message: "Unable to read list of files!",
});
}
};
const download = async (req, res) => {
try {
const [metaData] = await bucket.file(req.params.name).getMetadata();
res.redirect(metaData.mediaLink);
} catch (err) {
res.status(500).send({
message: "Could not download the file. " + err,
});
}
};
module.exports = {
upload,
getListFiles,
download,
};
我可以上传到我的bucket和list文件,但无法下载或在React前端查看图像预览。尝试使用下载API时,我收到以下消息:
- 匿名呼叫者没有对Google云存储对象的storage.objects.get访问权限。对资源的权限“storage.objects.get "被拒绝(或者资源可能不存在)。*
具体来说,这些是不起作用的:
const getListFiles = async (req, res) => {
try {
const [files] = await bucket.getFiles();
let fileInfos = [];
files.forEach((file) => {
fileInfos.push({
name: file.name,
url: file.metadata.mediaLink,
});
});
res.status(200).send(fileInfos);
} catch (err) {
console.log(err);
res.status(500).send({
message: "Unable to read list of files!",
});
}
};
const download = async (req, res) => {
try {
const [metaData] = await bucket.file(req.params.name).getMetadata();
res.redirect(metaData.mediaLink);
} catch (err) {
res.status(500).send({
message: "Could not download the file. " + err,
});
}
};
我不知道这里出了什么问题,因为我可以上传和列出文件-只是不能下载。有什么想法吗?
1条答案
按热度按时间mrphzbgm1#
确保服务帐户具有下载文件所需的权限。有关详细信息,请参阅此文档1和文档2。
经过身份验证的用户必须具有storage.objects.get IAM权限才能使用此方法。若要返回对象ACL,经过身份验证的用户还必须具有storage.objects.getIamPolicy权限。
同时初始化gcloud环境
gcloud init
,然后通过运行gcloud auth application-default login
设置应用程序默认凭据。