直传文件及Azure Storage的Blob服务中

(此文章以上于自身微信公众号“dotNET每日精华文章”,欢迎右边二维码来关注。)

题记:为了庆祝获得微信公众号赞赏功能,忙里抽闲分享一下以来干活的少数经验:如何直接由浏览器中达成传文书及Azure
Storage的Blob服务中。

为什么

苟您的Web应用程序利用了叙存储(比如Azure
Storage)来存储用户的资源文件(比如图片、视频等等)。通常的做法,是用户访问你的Web前端,上传文件及公的Web后端平采用,然后在后端程序中动用云存储的SDK把公文再度转传到讲话存储着。架构使下图所示:

图片 1

这种模式下,虽然简易方便。但是,由于上传文件之进程,需要盖Web后端程序作为代理,如果达到传文书巨大反复,会为后端程序的托管服务或者托管服务器造成较生运算压力及流量压力。所以,还有平等种植模式,是叫用户一直以浏览器中把文件上传给讲存储服务。我所熟知的云平台(Azure
,AWS,Aliyun)都提供了类似之特性,只是实现方式或者名称上有所不同。另外,在这种方法下,为了确保安全性,一般不会见直接将说存储的访Key暴露于Web前端,所以还见面供平等种折中方法,让你可非常成限时失效权限有限的共享访问Key,把此共享Key给到前端来取得访问能力。在Azure中,这个特点称之为共享访问签章(Shared
Access Signatures,SAS),而尽架构就改为下面这样:

图片 2

在这个架构中,你先从后端服务器获得SAS Url,然后径直上污染文书于Azure
Storage,上传文件成功后,如果需要还将有些文书首先数据传递给后端服务器(其实Azure的文本呢得以附加保存元数据的,你协调都足以不保险存元数据)。其实这种架构不仅可以采取于文件存储服务,在Azure中还可以于前者直接看Azure
Storage Table、Queue等劳务。关于SAS模型,微软官方的文档《Shared Access
Signatures, Part 1: Understanding the SAS
Model》(http://t.cn/R4OQona)讲的慌知,上面的觊觎就是是引自这首稿子。

自,在无数时刻,我们是亟需混用这点儿种植模式的,在需要再多安全控制和流量可控的情景,使用代理转传模式;在安康而隔离流量不可控的动静下,使用直传模式。我要好的实践当中,也是零星栽模式混用,在待用户上传文件及公共存储账号的时候,使用代理模式,在用户上传文件及用户独有存储账号的早晚,使用直传模式。

由于自己手上下的云平台是Azure,所以下面演示的代码也是基于Azure Storage
SDK的。

落SAS访问地址

根据Azure的文档《Shared Access Signatures, Part 2: Create and use a SAS
with Blob
storage》(http://t.cn/R4OQeBd)所陈述,获取SAS其实也非常简单。

第一实例化CloudStorageAccount、CloudBlobClient和CloudBlobContainer,如下:

//Parse the connection string and return a reference to the storage account.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("StorageConnectionString"));

//Create the blob client object.
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

//Get a reference to a container to use for the sample code, and create it if it does not exist.
CloudBlobContainer container = blobClient.GetContainerReference("sascontainer");
container.CreateIfNotExists();

接下来创建一个即之策略,调用CloudBlobContainer的GetSharedAccessSignature方法来扭转访问token,如下:

//Set the expiry time and permissions for the container.
//In this case no start time is specified, so the shared access signature becomes valid immediately.
SharedAccessBlobPolicy sasConstraints = new SharedAccessBlobPolicy();
sasConstraints.SharedAccessExpiryTime = DateTime.UtcNow.AddHours(24);
sasConstraints.Permissions = SharedAccessBlobPermissions.Write | SharedAccessBlobPermissions.List;

//Generate the shared access signature on the container, setting the constraints directly on the signature.
string sasContainerToken = container.GetSharedAccessSignature(sasConstraints);

所好成的token实际就是是一个分包有差不多只政策规则之查询字符串,然后把这token通过Web后端平的一个Api调用(当然是验证用户权限后)传递让Web前端。前端为使达到传的文件构造这样一个Url:存储容器的Uri+要达污染之公文称(包括所在文件夹)+SAS
Token,然后拿公文流HTTP PUT到这个Url就可以兑现上传。

上述代码生成的凡一个仓储容器的SAS Url,其实为堪对一个Blob对象生成SAS
Url。

除此以外待小心的是,你啊得在储存容器上设定一个恒定的共享访问策略(而未即设置于SAS
token上),这样你可以进一步便宜和体系的决定SAS的管事。详情而参考上面提到的文档。

设置跨域策略

直传文件实际上调用的是Azure Storage REST API,在初的时光,Azure
Storage是勿支持跨域访问的(CORS),在这种情形下,只有设置Storage容器的自定义域和Web应用程序的地面一致。不过本发生了CORS的支撑,就可怜简短了,通过下的点子可以安装CORS(:

public static async Task AddCorsRuleAsync(CloudBlobClient blobClient)
{
    //First get the service properties from storage to ensure we're not adding the same CORS rule again.
    var serviceProperties =await blobClient.GetServicePropertiesAsync();
    var corsSettings = serviceProperties.Cors;
    var corsRule = corsSettings.CorsRules.FirstOrDefault(
        o => o.AllowedOrigins.Contains("http://localhost:3904"));//设置你自己的服务器地址
    if (corsRule == null)
    {
        //Add a new rule.
        corsRule = new CorsRule()
        {
            AllowedHeaders = new List<string> { "x-ms-*", "content-type", "accept" },
            AllowedMethods = CorsHttpMethods.Put,//Since we'll only be calling Put Blob, let's just allow PUT verb
            AllowedOrigins = new List<string> { "http://localhost:3904" },//This is the URL of our application.
            MaxAgeInSeconds = 1 * 60 * 60,//Let the browswer cache it for an hour
        };
        corsSettings.CorsRules.Add(corsRule);
        //Save the rule
        await blobClient.SetServicePropertiesAsync(serviceProperties);
    }
}

对CORS更加详实的解说,可以参考Azure Storage的MSDN
Blog上之及时篇文章《Windows Azure Storage: Introducing
CORS》和Gaurav
Mantri的就篇博文《Windows Azure Storage and Cross-Origin Resource
Sharing (CORS) – Lets Have Some
Fun》

集成WebUploader

以赢得SAS并安装了CORS之后,最后之事务,就是何等把文件提交至SAS
Url了。虽然我们好动用Ajax或HTML5原生的主意来发送文书(如齐个别篇稿子被所示范的),但是采取一个存世的文件上传组件,应该是无与伦比有利于(对用户为是如此)的艺术了。

自家尝试了把Baidu
WebUploader集成,实现了大半图上传。在合龙的经过,一些只顾的地方发生:

  • 初始化uploader对象的时,不要设置server属性,因为server地址需要动态获取(要抱SAS
    Url),且每个文件之SAS Url不等同(因为文件称无同等)
  • 我是先事先获取SAS的token,然后以uploadStart事件被呢每个文件生成元数据信息,和分级的server地址
  • 在uploadBeforeSend事件中,来配置Azure所需的header信息
  • 以uploadSuccess事件受到,把公文之头版数据传递让后端服务器

现实的代码可以查阅自己享受的代码有:http://git.oschina.net/ike/codes/7edc84bio2zplhunyxvkr

末,如果立即篇稿子对你发因此,欢迎打赏。

相关文章