Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support uploads directly with signature #731

Merged
merged 1 commit into from
Jan 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
/* eslint max-len: [0] */
module.exports = {
extends: 'airbnb',
parserOptions: {
ecmaFeatures: {
experimentalObjectRestSpread: true,
},
},
env: {
browser: true,
node: true,
Expand Down
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ All operation use es7 async/await to implement. All api is async function.
- [.listParts(name, uploadId[, query, options])](#listparts-name-uploadid-query-options)
- [.listUploads(query[, options])](#listuploadsquery-options)
- [.abortMultipartUpload(name, uploadId[, options])](#abortmultipartuploadname-uploadid-options)
- [.calculatePostSignature(policy)](#calculatePostSignaturepolicy)
- [RTMP Operations](#rtmp-operations)
- [.putChannel(id, conf[, options])](#putchannelid-conf-options)
- [.getChannel(id[, options])](#getchannelid-options)
Expand Down Expand Up @@ -2550,6 +2551,22 @@ const result = await store.abortMultipartUpload('object', 'upload-id');
console.log(result);
```

### .calculatePostSignature(policy)

get postObject params

parameters:

- policy {JSON or Object} policy must contain expiration and conditions.

Success will return postObject Api params.

Object:

- OSSAccessKeyId {String}
- Signature {String}
- policy {Object} response info

## RTMP Operations

All operations function is [async], except `getRtmpUrl`.
Expand Down
42 changes: 42 additions & 0 deletions example/formPost.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
本文以JavaScript语言为例,讲解在服务端通过JavaScript代码完成签名,客户端通过请求获取签名,然后通过表单直传数据到OSS。

### 前提条件
应用服务器对应的域名可通过公网访问。
确保应用服务器已经安装node 8.*以上版本
确保PC端浏览器支持JavaScript。

### 步骤1:配置应用服务器
1. 下载应用服务器源码
2. 打开example/server/postObject.js文件
修改对应的`accessKeyId`、`accessKeySecret`、`bucket`配置
```
const config = {
accessKeyId: '<yourAccessKeyId>', //
accessKeySecret: '<yourAccessKeySecret>', //
bucket: '<bucket-name>'
}
```
如果使用通过STS临时授权方式进行表单直传, 则需要修改对应`STS_ROLE`配置
```
const STS_ROLE = '<STS_ROLE>';
```
3. 执行`npm install`
4. 执行`node postObject.js`

### 步骤2:修改CORS
客户端进行表单直传到OSS时,会从浏览器向OSS发送带有`Origin`的请求消息。OSS对带有`Origin`头的请求消息会进行跨域规则(CORS)的验证。因此需要为Bucket设置跨域规则以支持Post方法。

1. 登录[OSS管理控制台](https://oss.console.aliyun.com/?spm=a2c4g.11186623.2.16.548e4c07WTCBqs)。
2. 在左侧存储空间列表中,单击目标存储空间名称,打开该存储空间概览页面。
3. 单击**基础设置**页签,找到**跨域设置**区域,然后单击**设置**。
4. 单击**创建规则**,配置如下图所示。
![](http://static-aliyun-doc.oss-cn-hangzhou.aliyuncs.com/assets/img/9610949651/p12308.png)

### 步骤3:体验表单上传
1. 在浏览器输入`http://localhost:9000/`

2. 填写上传后的文件名称

3. 选择上传的文件

4. 单击**上传**按钮
4 changes: 3 additions & 1 deletion example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"server": "node server/app.js",
"watch": "webpack -w --config ./config/webpack.dev.conf.js",
"dev": "webpack-dev-server --config ./config/webpack.dev.conf.js",
"start": "node ./script.js"
"start": "node ./script.js",
"server-post": "node server/postObject.js"
},
"author": "",
"license": "MIT",
Expand All @@ -30,6 +31,7 @@
"dependencies": {
"ali-oss": "^6.0.0",
"bootstrap": "^4.1.1",
"express": "^4.17.1",
"jquery": "^3.3.1"
}
}
112 changes: 112 additions & 0 deletions example/server/postObject.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
const express = require('express');
const OSS = require('../../');
const { STS } = require('../../');

const app = express();
const path = require('path');

const config = {
accessKeyId: 'accessKeyId',
accessKeySecret: 'accessKeySecret',
bucket: 'bucket'
};

const STS_ROLE = 'STS_ROLE';

app.get('/postObject', async (req, res) => {
const client = new OSS(config);

const date = new Date();
date.setDate(date.getDate() + 1);
const policy = {
expiration: date.toISOString(), // 请求有效期
conditions: [
['content-length-range', 0, 1048576000] // 设置上传文件的大小限制
// { bucket: client.options.bucket } // 限制可上传的bucket
]
};

const formData = await client.calculatePostSignature(policy);
const url = `http://${config.bucket}.${
(await client.getBucketLocation()).location
}.aliyuncs.com`;
const params = {
formData,
url
};

res.json(params);
});
app.get('/postObjectBySTS', async (req, res) => {
if (STS_ROLE === 'STS_ROLE') {
res.status(500);
res.json({
message: '请修改 STS_ROLE '
});
}
const stsClient = new STS(config);

const date = new Date();
date.setDate(date.getDate() + 1);
const STSpolicy = {
Statement: [
{
Action: ['oss:*'],
Effect: 'Allow',
Resource: ['acs:oss:*:*:*']
}
],
Version: '1'
};

const formData = {};
try {
const result = await stsClient.assumeRole(
STS_ROLE,
STSpolicy,
3600 // token过期时间 单位秒
);
const { credentials } = result;

const client = new OSS({
accessKeyId: credentials.AccessKeyId,
accessKeySecret: credentials.AccessKeySecret,
bucket: config.bucket,
stsToken: credentials.SecurityToken
});

const policy = {
expiration: date.toISOString(), // 请求有效期
conditions: [
['content-length-range', 0, 1048576000] // 设置上传文件的大小限制
// { bucket: client.options.bucket } // 限制可上传的bucket
]
};

const signatureFormData = await client.calculatePostSignature(policy);
Object.assign(formData, signatureFormData);
formData['x-oss-security-token'] = credentials.SecurityToken;
const url = `http://${config.bucket}.${
(await client.getBucketLocation()).location
}.aliyuncs.com`;
const params = {
formData,
url
};

res.json(params);
} catch (error) {
res.status(500);
res.json(error);
}
});

app.use('/static', express.static('public'));
app.get('/', (req, res) => {
res.sendFile(path.resolve(__dirname, '../src/template/postObject.html'));
});

app.listen(9000, () => {
console.log('http://localhost:9000');
console.log('App of postObject started.');
});
Loading