@@ -5,6 +5,13 @@ import 'package:flutter_picgo/utils/net.dart';
55import 'package:flutter_picgo/utils/strings.dart' ;
66
77class QiniuApi {
8+ /// 管理Base_url,accesstoken和uptoken不共用baseurl
9+ static const String BASE_URL = "https://rs.qbox.me" ;
10+ static const String BASE_URL2 = "https://rsf.qbox.me" ;
11+
12+ static const String accessKey = 'accessKey' ;
13+ static const String secretKey = 'secretKey' ;
14+
815 /// 上传
916 static Future upload (
1017 String area, FormData data, Map <String , dynamic > headers) async {
@@ -14,18 +21,33 @@ class QiniuApi {
1421 }
1522
1623 /// 删除
17- static Future delete (url, String accessToken ) async {
24+ static Future delete (String url, String ak, String sk ) async {
1825 Response res = await NetUtils .getInstance ().post (url,
19- data: '' ,
2026 options: Options (
21- headers: {
22- "Authorization" : 'Qiniu $accessToken ' ,
27+ extra: {
28+ QiniuApi .accessKey: ak,
29+ QiniuApi .secretKey: sk,
2330 },
2431 contentType: 'application/x-www-form-urlencoded' ,
2532 ));
2633 return res.data;
2734 }
2835
36+ // 资源列举
37+ static Future list (Map <String , dynamic > query, String ak, String sk) async {
38+ Response res =
39+ await NetUtils .getInstance ().get ('${QiniuApi .BASE_URL2 }/list' ,
40+ queryParameters: query,
41+ options: Options (
42+ extra: {
43+ QiniuApi .accessKey: ak,
44+ QiniuApi .secretKey: sk,
45+ },
46+ contentType: 'application/x-www-form-urlencoded' ,
47+ ));
48+ return res.data;
49+ }
50+
2951 /// 上传凭证算法
3052 /// https://developer.qiniu.com/kodo/manual/1208/upload-token
3153 /// https://pub.flutter-io.cn/packages/crypto
@@ -60,8 +82,8 @@ class QiniuApi {
6082 signStr += '\n Content-Type: $contentType ' ;
6183 }
6284 signStr += '\n\n ' ;
63- if (contentType != 'application/octet-stream' ) {
64- signStr += body ?? '' ;
85+ if (contentType != 'application/octet-stream' && body != null ) {
86+ signStr += body;
6587 }
6688 // 使用SecertKey对上一步生成的原始字符串计算HMAC-SHA1签名:
6789 var hmacsha1 = Hmac (sha1, utf8.encode (secretKey));
@@ -70,6 +92,18 @@ class QiniuApi {
7092 return '$accessKey :$encodedSign ' ;
7193 }
7294
95+ /// 管理凭证历史文档
96+ /// https://developer.qiniu.com/kodo/manual/6671/historical-document-management-certificate
97+ static String generateAuthTokenByQBox (String path, String query, String body,
98+ String accessKey, String secretKey) {
99+ String signStr = '$path ?$query \n ${body ?? '' }' ;
100+ // 使用SecertKey对上一步生成的原始字符串计算HMAC-SHA1签名:
101+ var hmacsha1 = Hmac (sha1, utf8.encode (secretKey));
102+ var sign = hmacsha1.convert (utf8.encode (signStr));
103+ var encodedSign = urlSafeBase64Encode (sign.bytes);
104+ return '$accessKey :$encodedSign ' ;
105+ }
106+
73107 /// 生成putPolicy
74108 /// https://developer.qiniu.com/kodo/manual/1206/put-policy
75109 static String generatePutPolicy (String bucket, String key) {
@@ -106,3 +140,37 @@ class QiniuApi {
106140 }
107141 }
108142}
143+
144+ /// 七牛管理验签拦截器
145+ class QiniuInterceptor extends InterceptorsWrapper {
146+ @override
147+ Future onRequest (RequestOptions options) async {
148+ if (options.path.contains (QiniuApi .BASE_URL )) {
149+ String ak = '${options .extra [QiniuApi .accessKey ]}' ;
150+ String sk = '${options .extra [QiniuApi .secretKey ]}' ;
151+ options.data = options.data ?? '' ;
152+ var accessToken = QiniuApi .generateAuthToken (
153+ options.method,
154+ options.uri.path,
155+ options.uri.query,
156+ options.uri.host,
157+ options.contentType,
158+ options.data,
159+ ak,
160+ sk);
161+ options.headers.addAll ({
162+ 'Authorization' : 'Qiniu $accessToken ' ,
163+ });
164+ } else if (options.path.contains (QiniuApi .BASE_URL2 )) {
165+ String ak = '${options .extra [QiniuApi .accessKey ]}' ;
166+ String sk = '${options .extra [QiniuApi .secretKey ]}' ;
167+ options.data = options.data ?? '' ;
168+ var accessToken = QiniuApi .generateAuthTokenByQBox (
169+ options.uri.path, options.uri.query, options.data, ak, sk);
170+ options.headers.addAll ({
171+ 'Authorization' : 'QBox $accessToken ' ,
172+ });
173+ }
174+ return options;
175+ }
176+ }
0 commit comments