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设置,允许跨域。
客户端直接上传节省了服务器带宽和性能,提升客户体验。