1、阿里雲存儲服務端生成簽名
public class OssHelper { internal class PolicyConfig { public string expiration { get; set; } public List<List<Object>> conditions { get; set; } } internal class PolicyToken { public string accessid { get; set; } public string policy { get; set; } public string signature { get; set; } public string dir { get; set; } public string host { get; set; } public string expire { get; set; } public string callback { get; set; } } internal class CallbackParam { public string callbackUrl { get; set; } public string callbackBody { get; set; } public string callbackBodyType { get; set; } } // 請填寫您的AccessKeyId。 public static string accessKeyId = ""; // 請填寫您的AccessKeySecret。 public static string accessKeySecret = ""; // host的格式為 bucketname.endpoint ,請替換為您的真實信息。 public static string host = "my-demo-bucket.oss-cn-hangzhou.aliyuncs.com"; // callbackUrl為 上傳回調服務器的URL,請將下面的IP和Port配置為您自己的真實信息。 public static string callbackUrl = "http://88.88.88.88:8888"; // 用戶上傳文件時指定的前綴。 public static string uploadDir = "user-dir-prefix/"; public static int expireTime = 30; public static object GetPolicyToken() { //expireTime var expireDateTime = DateTime.Now.AddSeconds(expireTime); // example of policy //{ // "expiration": "2020-05-01T12:00:00.000Z", // "conditions": [ // ["content-length-range", 0, 1048576000] // ["starts-with", "$key", "user-dir-prefix/"] // ] //} //policy var config = new PolicyConfig(); config.expiration = FormatIso8601Date(expireDateTime); config.conditions = new List<List<Object>>(); config.conditions.Add(new List<Object>()); config.conditions[0].Add("content-length-range"); config.conditions[0].Add(0); config.conditions[0].Add(1048576000); config.conditions.Add(new List<Object>()); config.conditions[1].Add("starts-with"); config.conditions[1].Add("$key"); config.conditions[1].Add(uploadDir); var policy = JsonConvert.SerializeObject(config); var policy_base64 = EncodeBase64("utf-8", policy); var signature = ComputeSignature(accessKeySecret, policy_base64); //callback var callback = new CallbackParam(); callback.callbackUrl = callbackUrl; callback.callbackBody = "filename=${object}&size=${size}&mimeType=${mimeType}&height=${imageInfo.height}&width=${imageInfo.width}"; callback.callbackBodyType = "application/x-www-form-urlencoded"; var callback_string = JsonConvert.SerializeObject(callback); var callback_string_base64 = EncodeBase64("utf-8", callback_string); var policyToken = new PolicyToken(); policyToken.accessid = accessKeyId; policyToken.host = host; policyToken.policy = policy_base64; policyToken.signature = signature; policyToken.expire = ToUnixTime(expireDateTime); policyToken.callback = callback_string_base64; policyToken.dir = uploadDir; return policyToken; //return JsonConvert.SerializeObject(policyToken); } private static string FormatIso8601Date(DateTime dtime) { return dtime.ToUniversalTime().ToString("yyyy-MM-dd'T'HH:mm:ss.fff'Z'", CultureInfo.CurrentCulture); } private static string EncodeBase64(string code_type, string code) { string encode = ""; byte[] bytes = Encoding.GetEncoding(code_type).GetBytes(code); try { encode = Convert.ToBase64String(bytes); } catch { encode = code; } return encode; } private static string ComputeSignature(string key, string data) { using (var algorithm = new HMACSHA1()) { algorithm.Key = Encoding.UTF8.GetBytes(key.ToCharArray()); return Convert.ToBase64String( algorithm.ComputeHash(Encoding.UTF8.GetBytes(data.ToCharArray()))); } } private static string ToUnixTime(DateTime dtime) { const long ticksOf1970 = 621355968000000000; var expires = ((dtime.ToUniversalTime().Ticks - ticksOf1970) / 10000000L) .ToString(CultureInfo.InvariantCulture); return expires; } }
2、客戶端調用
$('#file').change(function () { var file = $(this).get(0).files[0]; $.ajax({ url: '/api/oss/GetPolicyToken', type: 'get', dataType: 'json', success: sign => { //這里使用服務器簽名方式,假設已經拿到服務器簽名信息 let _date = new Date() * 1; let data = new FormData(); data.append("Filename", `${sign.dir}${file.name}`); data.append("key", `${sign.dir}${file.name}`); data.append("policy", sign.policy); data.append("OSSAccessKeyId", sign.accessid); data.append("success_action_status", 200); data.append("signature", sign.signature); data.append('file', file, file.name); $.ajax({ url: 'https://'+sign.host, type: 'POST', processData: false, contentType: false, data: data, success: result => { console.log(result) } }) } }) })
3、阿里雲控制台OSS設置,允許跨域。
客戶端直接上傳節省了服務器帶寬和性能,提升客戶體驗。