官方文档:请求签名, Get Object
转载请注明出处: https://www.jianshu.com/p/49fe86909d18
Overview
本文使用dart按照腾讯COS文档生成签名,并使用签名下载COS文件对象到本地(使用flutter_download包)
载入crypto以及flutter_downloader包
在pubspec.yaml
文件中加入依赖(flutter_downloader文档,crypto文档)
Android: flutter_downloader 需要配置权限,请参考其文档。
dependencies:
flutter:
sdk: flutter
........
crypto: ^2.0.6
flutter_downloader: ^1.1.3
实现cos签名以及下载文件
import 'dart:convert';
import 'package:crypto/crypto.dart';
import 'package:flutter_downloader/flutter_downloader.dart';
class TencentCos {
static bool debug = true;
/// auth signature expired time in seconds
static final int signExpireTimeInSeconds = '10';
static final String secretId = 'tencentSerertId';
static final String secretKey = 'tencentSecretKey';
static final String bucketHost = 'yourBucketHost'; // xxx-xxxxxx.cos.ap-chengdu.myqcloud.com
static TencentCos _cos;
TencentCos._();
static TencentCos get() {
if (_cos == null) {
_cos = TencentCos._();
}
return _cos;
}
/// download $fileName and save to $saveDir(absolute path)
Future<String> downloadFile(String fileName, String saveDir) async {
var url = '/$fileName';
final taskId = await FlutterDownloader.enqueue(
headers: buildHeaders(url),
url: 'https://$bucketHost$url',
savedDir: saveDir,
fileName: fileName,
showNotification: false,
// show download progress in status bar (for Android)
openFileFromNotification: false,
// click on notification to open downloaded file (for Android)
);
return taskId;
}
Map<String, String> buildHeaders(String url) {
Map<String, String> headers = Map();
headers['HOST'] = bucketHost;
headers['Authorization'] = _auth('get', url, headers: headers);
if(debug) {
print(headers);
}
return headers;
}
String _auth(String httpMethod, String httpUrl,
{Map<String, String> headers, Map<String, String> params}) {
headers = headers ?? Map();
params = params ?? Map();
int currentTimestamp = DateTime.now().millisecondsSinceEpoch ~/ 1000;
var keyTime =
'$currentTimestamp;${currentTimestamp + signExpireTimeInSeconds}';
headers = headers.map((key, value) => MapEntry(key.toLowerCase(), value));
params = params.map((key, value) => MapEntry(key.toLowerCase(), value));
List<String> headerKeys = headers.keys.toList();
headerKeys.sort();
var headerList = headerKeys.join(';');
var httpHeaders = headerKeys
.map((item) => '$item=${Uri.encodeFull(headers[item])}')
.join('&');
List<String> paramKeys = params.keys.toList();
paramKeys.sort();
var urlParamList = paramKeys.join(';');
var httpParameters = paramKeys
.map((item) => '$item=${Uri.encodeFull(params[item])}')
.join('&');
var signKey = new Hmac(sha1, utf8.encode(secretKey))
.convert(utf8.encode(keyTime));
String httpString =
'${httpMethod.toLowerCase()}\n$httpUrl\n$httpParameters\n$httpHeaders\n';
var httpStringData = sha1.convert(utf8.encode(httpString));
String stringToSign = 'sha1\n$keyTime\n$httpStringData\n';
var signature =
new Hmac(sha1, utf8.encode(signKey.toString())).convert(utf8.encode(stringToSign));
String auth =
'q-sign-algorithm=sha1&q-ak=$secretId&q-sign-time=$keyTime&q-key-time=$keyTime&q-header-list=$headerList&q-url-param-list=$urlParamList&q-signature=$signature';
return auth;
}
}
使用示例
static final TencentCos _cos = TencentCos.get();
Future<String> _findLocalPath() async {
final directory = widget.platform == TargetPlatform.android
? await getExternalStorageDirectory()
: await getApplicationDocumentsDirectory();
return directory.path;
}
Future _requestDownload() async {
/// $yourLocalSaveDir is relative path
var _localPath = (await _findLocalPath()) + '$yourLocalSaveDir';
var taskId = await _cos.downloadFile('$yourFileNameInCos', _localPath);
}
更多
可根据自己需求,使用buildHeaders生成带签名的请求头,进行https请求。
网友评论