# AliOSSDemo
**Repository Path**: scenario-samples/ali-ossdemo
## Basic Information
- **Project Name**: AliOSSDemo
- **Description**: 【鸿蒙 Harmony Next 示例 代码】阿里OSS客户端上传demo
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 3
- **Forks**: 0
- **Created**: 2024-12-08
- **Last Updated**: 2025-04-21
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# API方式访问阿里云OSS
## 介绍
本示例介绍通过URL签名(v4)方式使用API访问阿里云OSS。
## 效果预览
## 使用说明
进入应用后,展示一个加号图标,点击图标即可选择要传输的图片,选择要传输的文件后,应用进行URL签名(v4)方式,即可使用API访问阿里云OSS。
## 实现思路
### 构造规范请求字段
1. 参数说明
| 参数 | 说明 |
| ---- | ---- |
| method | 请求方法,目前Demo中签名只支持`GET``PUT`两种请求 |
| contentType | 请求的媒体类型,只有在`PUT`请求时才需加入到签名中 |
| date | 日期,ISO8601格式的日期 |
| dateTime | 日期时间,ISO8601格式的日期时间 |
| expires | 签名URL的有效时长,单位为秒(s)。最小值为1,最大值为 604800(即7天) |
| bucketName | 存储空间名称 |
| path | 阿里云OSS上文件保存的根路径 |
| savePath | 阿里云OSS上文件的保存路径,包含文件名,不包含根路径字段 |
| ossRegion | 阿里云OSS所在区域 |
| accessKeyId | 临时接入KeyId |
| securityToken | 临时安全token |
2. PUT规范请求
```
PUT
/examplebucket/oss/path/test/test.txt
x-oss-additional-headers=host&x-oss-credential=accessKeyId%2F20240803%2Fcn-shanghai%2Foss%2Faliyun_v4_request&x-oss-date=20240803T130523Z&x-oss-expires=3600&x-oss-security-token=CAIS87WEEDddsada2F==&x-oss-signature-version=OSS4-HMAC-SHA256
content-type:text/plain
host:examplebucket.oss-cn-shanghai.aliyuncs.com
host
UNSIGNED-PAYLOAD
```
3. GET规范请求
```
GET
/examplebucket/oss/path/test/test.txt
x-oss-additional-headers=host&x-oss-credential=accessKeyId%2F20240803%2Fcn-shanghai%2Foss%2Faliyun_v4_request&x-oss-date=20240803T130523Z&x-oss-expires=3600&x-oss-security-token=CAIS87WEEDddsada2F==&x-oss-signature-version=OSS4-HMAC-SHA256
host:examplebucket.oss-cn-shanghai.aliyuncs.com
host
UNSIGNED-PAYLOAD
```
### 签名计算
1. 构造sha256Hex()函数,计算SHA256哈希值。
```typescript
public sha256Hex(data: string): string {
let sha256 = cryptoFramework.createMd('SHA256');
sha256.updateSync({ data: new Uint8Array(buffer.from(data, 'utf-8').buffer) });
let sha256Output = sha256.digestSync();
let output = buffer.from(sha256Output.data).toString('hex')
return output;
}
```
2. 构造函数zeroFormat(),获取当前日期和时间(ISO8601格式)。
```typescript
private zeroFormat(num: number, length: number = 2): string {
let format = '';
for (let i = 0; i < (length - num.toString().length); i++) {
format += '0';
}
format += num.toString();
return format;
}
private dateTimeISO8601(): string {
let date = new Date();
let rc = this.zeroFormat(date.getFullYear(), 4) + this.zeroFormat(date.getMonth() + 1) +
this.zeroFormat(date.getDate()) + 'T' + this.zeroFormat(date.getUTCHours()) +
this.zeroFormat(date.getMinutes()) + this.zeroFormat(date.getSeconds()) + 'Z';
return rc;
}
···
```
3. 构造canonicalRequest()函数,用以构造规范请求字符串,注意的是以下代码字符串顺序不能改变,否则与阿里云OSS上计算的签名不一致。
```typescript
private canonicalRequest(method: string, date: string, dateTime: string, pathOss: string, contentType: string = ''): string {
let canonicalRequest = method + "\n";
canonicalRequest += this.canonicalURI(pathOss);
canonicalRequest += this.canonicalQueryString(date, dateTime);
if (method === 'PUT') {
canonicalRequest += "content-type:" + contentType + '\n';
}
canonicalRequest += 'host:' + this.ossInfo.bucket_name + '.' + this.ossInfo.endpoint + '\n';
canonicalRequest += '\n';
canonicalRequest += 'host\n';
canonicalRequest += 'UNSIGNED-PAYLOAD';
return canonicalRequest;
}
```
4. 构造signString()函数,用以构造签名字符串,以下代码字符串顺序不能改变,否则与阿里云OSS上计算的签名不一致
```typescript
private signString(date: string, dateTime: string, canonical: string): string {
let stringToSign = '';
stringToSign += 'OSS4-HMAC-SHA256' + '\n';
stringToSign += dateTime + '\n';
stringToSign += date + '/' + this.ossRegion() + '/oss/aliyun_v4_request' + '\n';
stringToSign += canonical;
console.log(TAG, "stringToSign: " + stringToSign);
return stringToSign;
}
```
5. 构造calcSignature()函数,通过调用三方库CryptoJS方法去计算签名。
```typescript
private calcSignature(date: string, signString: string): string {
let dateKey: Uint8Array = CryptoJS.HmacSHA256(date, "aliyun_v4" + this.ossKey.AccessKeySecret);
let regionKey: Uint8Array = CryptoJS.HmacSHA256(this.ossRegion(), dateKey);
let regionServiceKey: Uint8Array = CryptoJS.HmacSHA256("oss", regionKey);
let signingKey: Uint8Array = CryptoJS.HmacSHA256("aliyun_v4_request", regionServiceKey);
let signature: string = CryptoJS.HmacSHA256(signString, signingKey).toString();
console.log(TAG, "response: signature: " + signature);
return signature;
}
```
## 一份简单的问卷反馈
亲爱的Harmony Next开发者,您好!
为了协助您高效开发,提高鸿蒙场景化示例的质量,希望您在浏览或使用后抽空填写一份简单的问卷,我们将会收集您的宝贵意见进行优化:heart:
[:arrow_right: **点击此处填写问卷** ](https://wj.qq.com/s2/19042938/95ab/)