Skip to content

Commit

Permalink
doc: add oss sign url docs
Browse files Browse the repository at this point in the history
  • Loading branch information
maslow committed Dec 1, 2023
1 parent de313cf commit 5d69be1
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 27 deletions.
1 change: 1 addition & 0 deletions docs/.vitepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ const guideSiderbarConfig = [
items: [
{ text: "云存储简介", link: "/guide/oss/" },
{ text: "云函数调用云存储", link: "/guide/oss/oss-by-function" },
{ text: "使用云函数生成上传和下载地址", link: "/guide/oss/gen-oss-url" },
{ text: "前端通过云函数上传文件", link: "/guide/oss/upload-by-function" },
{ text: "生成云存储临时令牌 (STS)", link: "/guide/oss/get-sts" },
{
Expand Down
4 changes: 2 additions & 2 deletions docs/guide/function/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ title: 云函数入门

## 云函数简介

`Laf云函数`是运行在云端的 `JavaScript` 代码。
`Laf云函数`是运行在云端的 `JavaScript` / `Typescript` 代码。

云函数可使用 `Typescript/JavaScript` 编写,无需管理服务器,在 Web 开发控制台在线编写、在线调试、一键保存即可运行后端代码。
云函数可使用 `JavaScript/Typescript` 编写,无需管理服务器,在 Web 开发控制台在线编写、在线调试、一键保存即可运行后端代码。

可在无需购买和管理服务器的情况下,快速开发后端代码。并且自带数据库和对象存储,极大降低后端开发难度。

Expand Down
6 changes: 3 additions & 3 deletions docs/guide/function/use-function.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,15 +74,15 @@ return ("Sorry, we cannot find that!"); // 字符串

### 方法 2: ctx.response 设置响应头、状态码和响应体等信息

这里`ctx.response`对齐`express`框架的`Response`实例
这里 `ctx.response` 对齐 `express` 框架的 `Response` 实例

以下是一些常见的 res 对象方法:
以下是一些常见的 response 对象方法:

```js
ctx.response.setHeader(name, value) // 设置一个响应头
ctx.response.send(body) // 发送响应体,可以是一个字符串、一个 Buffer 对象、一个 JSON 对象、一个数组等
ctx.response.json(body) // 发送一个 JSON 响应
ctx.response.status(statusCode) // 设置 HTTP 响应的状态码
ctx.response.setHeader(name, value) // 设置一个响应头
...
```

Expand Down
105 changes: 105 additions & 0 deletions docs/guide/oss/gen-oss-url.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
---
title: 使用云函数生成上传和下载地址
---

# {{ $frontmatter.title }}


## 生成上传地址

使用云函数生成一个临时的上传地址,客户端可直接使用该地址上传文件。

### 创建 `get-upload-url` 云函数

创建云函数 `get-upload-url`,添加如下代码:

```typescript
import cloud from '@lafjs/cloud'
import { S3, PutObjectCommand } from "@aws-sdk/client-s3"
import { getSignedUrl } from "@aws-sdk/s3-request-presigner"


const client = new S3({
region: cloud.env.OSS_REGION,
endpoint: process.env.OSS_EXTERNAL_ENDPOINT,
credentials: {
accessKeyId: cloud.env.OSS_ACCESS_KEY,
secretAccessKey: cloud.env.OSS_ACCESS_SECRET,
},
forcePathStyle: true,
})


export default async function (ctx: FunctionContext) {
const bucketName = `${process.env.APPID}-cloud-bin`

const command = new PutObjectCommand({
Bucket: bucketName,
Key: 'laf.json',
})

const url = await getSignedUrl(client, command, { expiresIn: 3600 * 24 })
return url
}

```

### 使用 curl 测试上传地址

```bash
# 获取上传地址
upload_url=$(curl -s https://YOUR_APPID.laf.run/gen-oss-upload-url)

# 上传文件
curl -X PUT -H "Content-Type: application/json" -d '{"name":"hi, laf"}' $upload_url
```

## 生成下载地址

使用云函数生成一个临时的下载地址,客户端可直接使用该地址下载文件。

### 创建 `get-download-url` 云函数

创建云函数 `get-download-url`,添加如下代码:

```typescript
import cloud from '@lafjs/cloud'
import { S3, GetObjectCommand } from "@aws-sdk/client-s3"
import { getSignedUrl } from "@aws-sdk/s3-request-presigner"


const client = new S3({
region: cloud.env.OSS_REGION,
endpoint: process.env.OSS_EXTERNAL_ENDPOINT,
credentials: {
accessKeyId: cloud.env.OSS_ACCESS_KEY,
secretAccessKey: cloud.env.OSS_ACCESS_SECRET,
},
forcePathStyle: true,
})

export default async function (ctx: FunctionContext) {
const bucketName = `${process.env.APPID}-cloud-bin`

const command = new GetObjectCommand({
Bucket: bucketName,
Key: 'laf.json',
})

const url = await getSignedUrl(client, command, { expiresIn: 3600 * 24 })
return url
}

```

### 使用 curl 测试下载地址

```bash
# 获取下载地址
download_url=$(curl -s https://YOUR_APPID.laf.run/gen-oss-download-url)

# 下载文件
curl -X GET $download_url
```


6 changes: 1 addition & 5 deletions docs/guide/oss/get-sts.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,7 @@ title: 生成云存储临时令牌 (STS)

# {{ $frontmatter.title }}

前端或云函数环境以外的地方需要请求云存储,是需要一个 STS 临时令牌的,下面云函数可以直接请求并获取一个 STS 临时令牌。

## 安装依赖

安装 `@aws-sdk/client-sts` 依赖(需重启应用生效)。
前端或云函数环境以外的地方需要管理云存储,是需要一个 STS 临时令牌的,下面云函数可以直接请求并获取一个 STS 临时令牌。

## 创建`get-oss-sts`云函数

Expand Down
38 changes: 21 additions & 17 deletions docs/guide/oss/upload-by-function.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ console.log(ctx.files)
还可以使用 nodejs 自带的 `fs`库 来获取文件对象

```javascript
var fs = require("fs");
var data = await fs.readFileSync(ctx.files[0].path);
import { readFile } from 'fs/promises'
const data = await readFile(ctx.files[0].path)
```

- data 里面就是文件对象
Expand All @@ -69,9 +69,11 @@ var data = await fs.readFileSync(ctx.files[0].path);
如:`uploadFile`,代码如下:

```typescript
import cloud from "@lafjs/cloud";
import { GetObjectCommand, S3 } from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
import cloud from "@lafjs/cloud"
import { GetObjectCommand, S3 } from "@aws-sdk/client-s3"
import { getSignedUrl } from "@aws-sdk/s3-request-presigner"
import { readFile } from 'fs/promises'

const s3Client = new S3({
endpoint: process.env.OSS_EXTERNAL_ENDPOINT,
region: process.env.OSS_REGION,
Expand All @@ -81,26 +83,27 @@ const s3Client = new S3({
},
forcePathStyle: true,
})
var fs = require("fs");

const bucketName = 'bucketName' // 不带 Laf 应用 appid

//拼接文件桶名字
function getInternalBucketName() {
const appid = process.env.APP_ID;
return `${appid}-${bucketName}`;
const appid = process.env.APP_ID
return `${appid}-${bucketName}`
}

//上传文件
async function uploadAppFile(key, body, contentType) {
const bucket = getInternalBucketName();
const bucket = getInternalBucketName()
const res = await s3Client
.putObject({
Bucket: bucket,
Key: key,
ContentType: contentType,
Body: body,
})
return res;

return res
}

//获取文件 url
Expand All @@ -109,21 +112,22 @@ async function getAppFileUrl(key) {
const res = await getSignedUrl(s3Client, new GetObjectCommand({
Bucket: bucket,
Key: key,
}));
return res;
}))

return res
}

export default async function (ctx: FunctionContext) {
//获取上传文件的对象
var data = await fs.readFileSync(ctx.files[0].path);
const data = await readFile(ctx.files[0].path);
const res = await uploadAppFile(
ctx.files[0].filename,
data,
ctx.files[0].mimetype
);
const fileUrl = await getAppFileUrl(ctx.files[0].filename);
return fileUrl;
};
return fileUrl
}
```

## 测试上传
Expand Down Expand Up @@ -152,8 +156,8 @@ const bucketName = 'bucketName' // 不带 Laf 应用 appid

//拼接文件桶名字
function getInternalBucketName() {
const appid = process.env.APP_ID;
return `${appid}-${bucketName}`;
const appid = process.env.APPID
return `${appid}-${bucketName}`
}

export default async function (ctx: FunctionContext) {
Expand Down

0 comments on commit 5d69be1

Please sign in to comment.