ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Laf 云存储详解:S3 兼容对象存储、存储桶权限模型、网站托管与 Cloud Bin 机制

Laf 云存储详解:S3 兼容对象存储、存储桶权限模型、网站托管与 Cloud Bin 机制 Laf 云存储详解S3 兼容对象存储、存储桶权限模型、网站托管与 Cloud Bin 机制【免费下载链接】lafLaf is a vibrant cloud development platform that provides essential tools like cloud functions, databases, and storage solutions. It enables developers to quickly unleash their creativity and bring innovative ideas to life with ease.项目地址: https://gitcode.com/GitHub_Trending/la/lafLaf 云存储是一个兼容 S3 API 的对象存储服务为云函数、客户端应用提供文件上传、下载、删除与列表等能力同时支持将存储桶发布为静态网站。阅读本文后你将理解存储桶的命名与隔离规则、三种桶权限的适用场景、网站托管的开启方式以及 Laf 为每个应用自动创建的 Cloud Bin 系统桶的用途并能结合lafjs/cloudSDK 与仓库源码验证这些行为的底层实现。云存储是什么laf云存储是兼容 S3 API 的对象存储服务支持多种存储桶权限公有读、私有读、公有读写支持通过 HTTP/HTTPS 访问支持自定义文件元数据支持文件上传、下载、删除、获取文件列表等操作。从 SDK 实现看这些操作并非自造协议packages/cloud-sdk/src/storage.ts 中的CloudStorage与CloudStorageBucket类直接基于aws-sdk/client-s3构建readFile、writeFile、deleteFile、listFiles分别对应 S3 的GetObject、PutObject、DeleteObject、ListObjects命令上传/下载地址则由aws-sdk/s3-request-presigner的getSignedUrl生成签名 URL。因此熟悉 S3 的开发者可以直接迁移到 Laf 云存储上。CloudStorage内部维护了两类 S3 客户端分别走不同端点所需的环境变量在运行时断言中清晰可见客户端端点环境变量用途getExternalS3Client()OSS_EXTERNAL_ENDPOINT通过外网端点访问桶用于生成对外签名 URLgetInternalS3Client()OSS_INTERNAL_ENDPOINT通过内网端点读写文件readFile/writeFile/deleteFile/listFiles均走此客户端两者还共同依赖OSS_REGION、OSS_ACCESS_KEY、OSS_ACCESS_SECRET并统一设置forcePathStyle: true以路径风格寻址桶即endpoint/{bucket}/{key}形式。存储桶Bucket在云存储中存储桶是存储文件的容器所有的文件都必须存储在存储桶中每个存储桶都有一个唯一的名称。云存储支持创建多个存储桶每一个存储桶都是一个独立的存储空间文件桶的名称必须遵守以下规则名称必须是全局唯一的只能包含小写字母、数字和-字符长度不能超过 63 个字符。appid 前缀应用级隔离的关键在 laf 应用中文件桶的名称是由应用的appid作为前缀然后加上存储桶的名称例如{appid}-bucket这样可以保证每个应用的文件桶名称都是唯一的。这一规则在 SDK 侧有明确的代码实现。cloud.storage.bucket(bucketName)在 packages/cloud-sdk/src/storage.ts 中的逻辑是bucket(bucketName: string): CloudStorageBucket { assert(bucketName, bucketName is required) if (IS_SEALAF || bucketName.startsWith(${this.appid}-)) { return new CloudStorageBucket(this, bucketName) } const name ${this.appid}-${bucketName} return new CloudStorageBucket(this, name) }也就是说调用cloud.storage.bucket(data)时若当前环境注入了APPIDSDK 会自动将其解析为{appid}-data这个真实桶名若传入的名字已经带上了{appid}-前缀则原样使用。appid本身来自云函数运行时的process.env.APPID缺失时会在断言处直接抛错。在服务端server/src/storage/bucket.service.ts 的create方法会先以dto.fullname(appid)拼出完整桶名写入系统数据库的StorageBucket集合初始状态为Active/Creating随后由后台任务在底层对象存储MinIO中真正创建该桶——从 server/src/storage/bucket.service.ts 中updateBucketPolicy经由MinioService调用的链路可以推断Laf 的对象存储后端为 MinIO这也解释了其 API 与 S3 完全兼容的原因。存储桶权限云存储支持多种存储桶权限在创建存储桶时可以指定桶的权限。文档与源码中的权限对照如下权限含义读取写入public公有读写无需凭证即可读写桶中的文件无需凭证无需凭证readonly公有读无需凭证即可读写需要凭证无需凭证需要凭证private私有读写读写都需要凭证需要凭证需要凭证通常不建议使用public权限因为这样会导致存储桶中的文件可以被任何人访问。服务端对权限的建模见 server/src/storage/entities/storage-bucket.tsexport enum BucketPolicy { readwrite readwrite, readonly readonly, private private, }从源码结构看文档中称公有读写权限为public而在服务端的BucketPolicy枚举中对应的存储值是readwrite修改权限时BucketService.updateOne会同步调用 MinIO 更新桶策略只有底层返回204才会落库更新保证了数据库记录与对象存储策略的一致性。权限与文件访问方式的关系权限直接决定了获取文件访问地址的方式这也是 SDK 中 URL 方法的设计依据见 packages/cloud-sdk/src/storage.ts桶权限为public或readonly时可直接使用公共访问地址bucket.externalUrl(filename)拼接出{externalEndpoint}/{bucket}/{key}形式的永久地址永久有效除非桶权限被修改桶权限为private时必须生成带签名的临时访问地址bucket.getDownloadUrl(filename, expiresIn)默认有效期3600 秒1 小时最大可设置为3600 * 24 * 7秒7 天客户端拿到 URL 后无需任何凭证即可直接下载。对应地上传侧的bucket.getUploadUrl(filename, expiresIn)同样默认 1 小时、最长 7 天客户端使用返回的 URL 直接PUT上传文件。云函数中操作文件以上述权限模型为基础在云函数中通过lafjs/cloud操作存储桶的典型用法如下示例使用data存储桶使用前需先在控制台创建该桶上传文件import cloud from lafjs/cloud export default async function (ctx: FunctionContext) { // 获取存储桶 const bucket cloud.storage.bucket(data) // 写文件 const content hello, laf await bucket.writeFile(laf.html, content) }writeFile的body参数接受string | Blob | Buffer | Uint8Array | Readable流见 storage.ts 的签名文件类型默认是application/octet-stream需要时通过options.ContentType指定await bucket.writeFile(index.html, content, { ContentType: text/html })上传本地文件可以用文件流或 Bufferimport cloud from lafjs/cloud import { createReadStream } from node:fs import { readFile } from node:fs/promises // 方式一文件流 const stream createReadStream(./package.json) await bucket.writeFile(laf.json, stream, { ContentType: application/json }) // 方式二Buffer const buffer await readFile(./package.json) await bucket.writeFile(laf.json, buffer, { ContentType: application/json })读取、删除与列表// 读文件并转为字符串 const res await bucket.readFile(index.html) const data await res.Body.transformToString() // 读文件为 Buffer const bytes await res.Body.transformToByteArray() const buffer Buffer.from(bytes) // 删除文件注意即使文件不存在也会正常返回不会抛出异常 await bucket.deleteFile(index.html)listFiles返回S3 ListObjects风格的结果res.Contents中每个对象包含Key、LastModified、ETag、Size字段。它支持三类常用参数Delimiter: /只列当前目录对象名按分隔符分组Prefix: images/筛选指定前缀子目录下的对象MaxKeys: 10限定单次返回数量默认 1000。分页依赖返回结果中的IsTruncated与NextMarker前者表示是否还有下一页后者作为下一页的Marker参数传入。// 获取 images/ 子目录下、前 10 个文件 const res await bucket.listFiles({ Prefix: images/, Delimiter: /, MaxKeys: 10 })网站托管laf云存储支持将存储桶中的文件作为静态网站进行托管开启步骤如下将存储桶的权限设置为readonly——只有readonly权限的存储桶才能作为静态网站进行托管在 laf 控制台中开启存储桶的网站托管功能在存储桶中创建一个名为index.html的文件作为默认首页。开启后 Laf 会自动为网站提供一个独立的访问域名也可以绑定自定义域名。绑定自定义域名网站托管支持绑定自己的域名并会自动为其生成 HTTPS 证书同时支持http和https访问。按页面提示完成域名的CNAME解析解析生效通常 110 分钟后即可继续绑定操作绑定后 Laf 会自动为域名配置 SSL 证书该过程约需 12 分钟之后即可通过https访问。从服务端代码结构看桶与域名、网站托管的关联关系是显式建模的BucketService.findOne/findAll通过聚合查询将BucketDomain自定义域名与WebsiteHosting集合关联到每个存储桶上见 server/src/storage/bucket.service.ts控制台的域名绑定与托管开关正是维护这些关联数据。Cloud Bin BucketLaf 会为每个应用自动创建一个名为{appid}-cloud-bin的存储桶用于存储应用的缓存和备份文件。该存储桶默认权限为private建议不要修改该存储桶的权限。其实现位于 server/src/storage/cloud-bin-bucket.service.tsensureCloudBinBucket(appid)会先查询{appid}-cloud-bin是否已存在不存在时以BucketPolicy.private策略自动创建async ensureCloudBinBucket(appid: string) { const shortName cloud-bin const bucketName ${appid}-${shortName} const bucket await this.bucketService.findOne(appid, bucketName) if (bucket) { return bucket } const dto new CreateBucketDto() dto.shortName shortName dto.policy BucketPolicy.private const created await this.bucketService.create(appid, dto) return created }此外该服务还提供createPullUrl/createPushUrl两个方法基于getSignedUrl为指定文件生成有效期 7 天expiresIn: 3600 * 24 * 7的拉取/推送签名 URL从源码结构看这正是“应用缓存和备份文件”在私有桶中安全读写的通道。小结Laf 云存储围绕“S3 兼容 应用隔离”两个核心设计展开应用隔离桶名强制{appid}-前缀SDK 自动拼接、全局唯一且限 63 字符内的小写字母/数字/-权限模型public/readonly/private三档权限决定了使用公共地址还是签名地址访问文件网站托管readonly桶可一键托管为静态网站支持自动域名与自定义域名 自动 HTTPS 证书Cloud Bin每应用私有系统桶{appid}-cloud-bin承载缓存与备份不应变更其权限。相关文档可进一步参考 上传文件、读取文件、生成下载地址、生成上传地址、文件列表、删除文件 与 网站托管实现细节可深入 packages/cloud-sdk/src/storage.ts、server/src/storage/bucket.service.ts 与 server/src/storage/cloud-bin-bucket.service.ts。【免费下载链接】lafLaf is a vibrant cloud development platform that provides essential tools like cloud functions, databases, and storage solutions. It enables developers to quickly unleash their creativity and bring innovative ideas to life with ease.项目地址: https://gitcode.com/GitHub_Trending/la/laf创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表