ali-oss 签名问题,文件直传&私有文件授权访问

ali-oss 签名经常不对,特此记录一下,下面的代码是flutter的,原理是一样的。主要是签名message的拼接方式,特别容易错还不容易校验。

1. PubObject 文件上传 文档链接


import 'dart:convert';
import 'dart:io';
import 'package:crypto/crypto.dart';
import 'package:dio/dio.dart';
import 'package:flutter_network/flutter_network.dart';
import 'package:flutter_oss/src/constance.dart';
import 'package:flutter_oss/src/oss_model.dart';
import 'package:intl/intl.dart';
import 'package:intl/date_symbol_data_local.dart';
import 'package:mime/mime.dart';

typedef SendProgress = Function(int send, int total);

class UploadOSS {
  static Future upload(
      {required File file,
      required String bucket,
      required String regionId,
      required String destinePath,
      required TicketModel ticketModel,
      SendProgress? onSendProgress}) async {
    try {
      var verb = "PUT";
      var contentMd5 = "";
      var contentType = lookupMimeType(file.path);
      var date = requestTime();

      var canonicalizedOSSHeaders =
          "x-oss-security-token:" + ticketModel.securityToken! + "\n";
      var canonicalizedResource = "/" + bucket + "/" + destinePath;
      var message = '''$verb
$contentMd5
$contentType
$date
$canonicalizedOSSHeaders$canonicalizedResource''';
/*
测试数据  
var message = "PUT

text/plain
Fri, 23 Sep 2022 10:17:14 GMT
x-oss-security-token:CAISqAJ1q6Ft5B2yfSjIr5fzEszWn7h4gaSDekncs0YmdOtclpXtlzz2IHlLfnZuA+oYt/w+mGxY6fsflqMpFs5tS1OBZNNotgTdFZV8O9ivgde8yJBZonfMewHKeQuZsebWZ+LmNpy/Ht6md1HDkAJq3LL+bk/Mdle5MJqP+/kFC9MMRVuAcCZhDtVbLRcYi618D3bKMuu3ORPHm3fZCFES2jBxkmRi86+ysIr+rxPVlw/90fRH5dazcJK+ZshqN5A6WNCw2etwM7Lc2ipR4F9X76psl+sepGaA/PPlWggMs07farCLo4A2dlMoOZJXQfAU8KLO8tRjofHWmojNzBJAAPpYSSy3Rvr7mZSeR73zbIhgLeenZySSj42VWIP8tgQ/emLCy9ijvRD0QRqAARfutxqmwUeuT/zdLXzswFDDtAj7255Cw50XXesX2mUwzGGfP/hEz+7Fh8vjsRAnp56DwfEN/Ph8hpwY+Rui3XtEvxDKe27GE+yH0zgKldi2Kh1eam8sdiNVCUqMyzTYhqg8tQsiTt3suQrrLEuyZylKz5UVEfNrf/ygoRGnF/lq
/brainco-common-public/users/259/dev/test_files/1663928233935-1392323866593.txt"
var signature =
        var signature = UploadOSS.getSignature(message,"BKtAoNjTZ95WqUhHC8HopovJbmRKKotPZHneLHG3SNrJ");
signature 应该是: gg4uLupC6MqgAOiC+dPq8qAGMB8=
*/
      var signature = getSignature(message, ticketModel.accessKeySecret!);
      var authorization = "OSS " + ticketModel.accessKeyId! + ":" + signature;

      //bucket xxxx-common-public
      var url = 'https://$bucket.oss-$regionId.aliyuncs.com/$destinePath';
      //https://xxxx-common-public.oss-cn-hangzhou.aliyuncs.com/test-1.png
      var length = file.lengthSync();
      //速度快 有进度
      Stream> stream =
          MultipartFile.fromFileSync(file.path).finalize();
      var response = await FocusHttpUtil(tag: kDioTag).rest.put(url,
          data: stream,
          onSendProgress: onSendProgress,
          options: Options(headers: {
            'authorization': authorization,
            'content-Type': contentType,
            'date': date,
            'x-oss-security-token': ticketModel.securityToken,
            'Content-Length': length
          }));

      if (response.statusCode == 200) {
        return url;
      }
      throw response.toString();
      // 成功后返回文件访问路径
    } catch (e) {
      throw e.toString();
    }
  }

  /// 获取文件类型
  static String getFileType(String path) {
    var array = path.split('.');
    return array[array.length - 1];
  }

  /// 获取签名
  static String getSignature(String policyText, String ossAccessKeySecret) {
    final digest = Hmac(sha1, utf8.encode(ossAccessKeySecret))
        .convert(utf8.encode(policyText));
    return base64.encode(digest.bytes);
  }

  static String requestTime() {
    initializeDateFormatting('en', null);
    final DateTime now = DateTime.now();
    final String string =
        DateFormat('EEE, dd MMM yyyy HH:mm:ss', 'en_ISO').format(now.toUtc());
    return '$string GMT';
  }
}

私有文件访问 授权访问

注意:此处的签名和PubObject的message不一致

static Future getAuthorityUrl(
      {required String url, required String token}) async {
    if (!url.contains('-private.')) {
      return url;
    }
    var path = url.split('.aliyuncs.com/')[1];
    RegExp exp = RegExp(r"\w+://(.*?).oss");
    var bucket = exp.firstMatch(url)?.group(1);

    RegExp exp2 = RegExp(r".+oss-(.*?).aliyuncs.com");
    var regionId = exp2.firstMatch(url)?.group(1);

    var ticketModel = await OSSApi.getReadTicket(bucket!, regionId!, token);

    var verb = "GET";
    var contentMd5 = "";
    var contentType = "";
    final DateTime now = DateTime.now().add(const Duration(hours: 1));
    final expires = now.millisecondsSinceEpoch ~/ 1000;

    var canonicalizedOSSHeaders =
        "security-token=" + ticketModel.securityToken!;
    var canonicalizedResource = "/" + bucket + "/" + path;
    //特别注意
    var message = """$verb
$contentMd5
$contentType
$expires
$canonicalizedResource?$canonicalizedOSSHeaders""";

/*
测试数据  
var message = "GET


1663931316
/brainco-common-private/testfile/1.txt?security-token=CAISngJ1q6Ft5B2yfSjIr5f9fO38gugX8fuldUnGqjkNQehth5P+iDz2IHlLfnZuA+oYt/w+mGxY6fsflqMpFs5tS1OBZNNoth2qdJZ8O9ivgde8yJBZoozHcDHhF3yW9cvWZPqDA7G5U/yxalfCuzZuyL/hD1uLVECkNpv77vwCac8MDCa1cR1MBtpdOnFIyqkgOGDWKOymPzPzn2PUFzAIgAdnjn5l4qnNjK/Q4xHF3lrh0b1X9cajKIKtbs9nO9J0VNKw2+ozbrDAzidM5l8I1t8v3fEUom6e5I7MXgALv0TZCYeOrI0zdj0eT7MhBqtJoML7kfBFoeHJn+z1sU0UYrsKDX6FGtn4kZeYSLz0a8xXb7/+PG/Wwglw7XAzedZPGoABjJ8Gnx8H7Tpne0Akd3JFZx7E1rBtCDErKOF4H8HO0/bmZ+MiTaQmcxWiwUF8SSAYHetMhKcp0xoZZQUSx29AZvPmvsAHb660dXaTbriic+ncmMPsvt+tDrKz77xKe82xM39A806rGMoJC23bNepJ3fCaHN3Oy+cMBbhsFd1ViAw="
var signature =
        var signature = UploadOSS.getSignature(message,"nZGCDZxRnp2KUrxAzvg1KicAFQqVPz3qbcdw6n5VCb2");
signature 应该是: wtE6jMCrgSxRY6FFrcYq/tCYwFA=
*/
    var signature =
        UploadOSS.getSignature(message, ticketModel.accessKeySecret!);
    var result =
        'OSSAccessKeyId=${ticketModel.accessKeyId}&Expires=$expires&Signature=${Uri.encodeQueryComponent(signature)}&security-token=${Uri.encodeQueryComponent(ticketModel.securityToken!)}';

    return '$url?$result';
  }

你可能感兴趣的:(ali-oss 签名问题,文件直传&私有文件授权访问)