阿里云OSS设置Referer防盗链后MP3/MP4文件在浏览器无法播放问题的分析

    笔者使用阿里云的OSS产品作为网站静态文件和一些流媒体文件(MP3/MP4)的存储空间,为了防止流量被盗刷,设置了Referer防盗链,如下图所示:

    *.your-site.com是你绑定到OSS源站点的域名,也就是将域名解析到OSS的源地址xxx.oss-cn-beijing.aliyuncs.com。笔者最开始并没有添加图中的以下这两个域名:*.aliyuncs.com,*.console.aliyun.com,其实这两个域名各有用处,下面逐一说明:

1、*.aliyuncs.com

    如果在浏览器输入OSS存储的图片路径(bucketname.oss-cn-beijing.aliyuncs.com/xx.png),当发起请求的时,因为header不包含Rerefer字段,图片是可以正常显示的,但是奇怪的是浏览器如果输入是一个mp3文件的oss路径 (bucketname.oss-cn-beijing.aliyuncs.com/1/21/test9.mp3),虽然没有显示禁止访问的403 forbidden错误页面,但也无法在浏览器正常播放(只显示了一个黑色播放控件,然后看到一个加载进度条一直转圈圈),后面在官方文档「防盗链」找到了解释:

当您使用OSS的Bucket域名(如bucketname.oss-cn-zhangjiakou.aliyuncs.com)预览MP4文件时,由于浏览器默认会同时发出两个请求,其中一个为带Referer的请求,另一个为空Referer的请求,因此设置防盗链时必须同时满足在Referer中添加Bucket域名,且允许空Referer的条件。当您使用OSS的Bucket域名预览非MP4文件时,则仅需允许空Referer。

    因此我将*.aliyuncs.com 加入到Refere的白名单里,就可以正常播放MP3/MP4媒体文件了,但是这里为什么会有两个请求呢?笔者先打开chrome控制台的「网络」模块,然后在地址栏输入文件路径后,点击确认发起请求时,确实看到有两个“看似相同”的请求,如下图:

 

    在控制台可以看到两个对文件“test9.mp3”的请求,但是第一个返回状态码是200,header有不含Referer字段,第二个返回的状态码是:206 Partial Content(状态码206 Partial Content),并且可以看到第二个请求的header有Referer字段,OSS源站点就会拿这个Referer字段和OSS设置的Referer白名单进行比较,如果通过了就正常访问,没有通过就会返回403 forbidden 错误。

    特别注意:如果OSS的Referer白名单设置为xxx.oss-cn-beijing.aliyuncs.com,在浏览器仍然无法正常播放MP3/MP4文件,可以在浏览器的控制台看到“test9.mp3”的第二个请求发生了403 forbidden 错误,说明请求的referer不满足oss的referer规则,原因是第二次请求的Referer的路径(http://bucketname.oss-cn-beijing.aliyuncs.com/test9.mp3)带上了http://协议头,无法匹配OSS的设置的Referer规则,如果将OSS的Referer白名单添加上http协议(http://xxx.oss-cn-beijing.aliyuncs.com)进行精确匹配就可以正常播放了,或者OSS的referer白名单添加的域名统一加上前缀  “ *. ”(*.aliyuncs.com) 实现模糊匹配也是行得通的。 

以上对域名*.aliyuncs.com的原理分析,同样的道理也是使用于域名*.your-site.com

2、*.console.aliyun.com

    如果开启了Refere设置,但是没有添加 *.console.aliyun.com,在OSS的Bucket​​​​​的文件管理详情页面图片无法预览:

    点击下载文件时,会无法正常下载,并弹出提示框:

    因此按照提示,将*.console.aliyun.com添加到Referer白名单后,上面的问题就解决了,但是笔者已经设置了允许Referer为空,为什么无法预览和正常下载文件,笔者暂时没有想明白,按照官方文档对Referer的设置逻辑,除非这两个操作都提交了Referer内容,但是提交的Referer不在OSS的Referer白名单列表之内才会导致操作失败。

3、Android / IOS 客户端

    客户端要正常的显示图片,播放音频/视频,下载文件,需要服务端OSS允许空的Referer,因为客户端请求Header的Referer的字段为空;如果不允许为空,则需要在客户端在请求服务端资源的时候添加符合条件的Referer字段。

猜你喜欢

转载自blog.csdn.net/crazestone0614/article/details/127254356
今日推荐