前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >用NginScript做个带权限的文件分发服务

用NginScript做个带权限的文件分发服务

原创
作者头像
黄希彤
修改2021-11-11 14:23:47
5410
修改2021-11-11 14:23:47
举报
文章被收录于专栏:黄希彤的专栏黄希彤的专栏

之前有个带权限验证的CDN服务,没有同步开通海外CDN,一直用一台香港的服务器提供文件服务。为了实现和CDN一样的权限算法,是用Node做的服务器。JS做权限验证逻辑当然是非常轻松的,但是Node做文件服务就有点力不从心了,读文件流,写http流,零拷贝不知道怎么实现,似乎还有定位不出来的内存泄漏之类的问题,服务过几天就莫名其妙的会死一下,还要写个监控把它拉起来。

其实一直知道Nginx+Lua可能是最佳解决方案了,不过想想专门去学习一个在其他场合好像也没啥用处的语言……还是让Node服务去重启吧。

直到发现了NginScript(NJS),这就很适合用javascript写着这种无状态的计算服务嵌入到文件分发流程中了。

安装最新的Nginx+NJS,服务器是CentOS 8.2,选择了相应的rpm包:

代码语言:javascript
复制
rpm -Uvh https://nginx.org/packages/centos/8/x86_64/RPMS/nginx-1.20.1-1.el8.ngx.x86_64.rpm
rpm -Uvh https://nginx.org/packages/centos/8/x86_64/RPMS/nginx-module-njs-1.20.1%2B0.7.0-1.el8.ngx.x86_64.rpm

文件一直是在COS里面管理,通过COS分发到CDN的,最简单的让Nginx分发COS的方式是用COSFS把bucket挂载到/mnt目录下。不过8.0+的CentOS系统用yum安装COSFS的时候不兼容,要下载编译:

代码语言:javascript
复制
 yum install automake gcc-c++ git libcurl-devel libxml2-devel fuse-devel make openssl-devel fuse
git clone https://github.com.cnpmjs.org/tencentyun/cosfs /usr/cosfs
cd /usr/cosfs
./autogen.sh
./configure
make
sudo make install
cosfs --version

github访问经常连不上,换了加速站点 github.com.cnpmjs.org 才顺利下载到。

因为要对文件访问做权限,所以挂载了COS的目录somewhere不能直接在Nginx里对外开放,要对内开放,只允许经过验证的请求用内部重定向的方式下载:

代码语言:javascript
复制
    load_module modules/ngx_http_js_module.so;
    ......
    http {
    ......
    js_import http.js;
    ......
    
    location /somewhere{
        internal;
        root /mnt/somewhere/;
    }
    
    location / {
        js_content http.redirect;
    }

这样外部来的http请求直接到http.js里面去鉴权通过了才能去访问到somewhere:

代码语言:javascript
复制
function redirect(r) {
	for(var i in headers){
		r.headersOut[i]=headers[i];
	}

	if(r.method == "OPTIONS"){
		r.return(200, "ok");
	}else{
		var pathname = r.uri;
		if(/\.((jpe?g)|(png)|(gif)|(ico)|(html?))$/.test(r.uri)){
			r.internalRedirect('/somewhere'+r.uri);
		}else if(r.args && r.args.data){
			var checkResult = checkAuth(decodeURIComponent(r.args.data));
			if(checkResult){
				r.internalRedirect('/somewhere'+checkResult);
			}else{
				r.internalRedirect('/somewhere/404.html');
			}
		}else{
			r.internalRedirect('/somewhere/404.html');
		}
	}
}

export default {redirect};

鉴权算法:

代码语言:javascript
复制
function checkAuth(fullpath){
	const crypto = require('crypto'),
	rFullPath = /https:\/\/www.myDomainName.com([^\.]*\.mp3)\?sign=([\d]+)\-([0-9a-z]+)\-([0-9]+)\-([0-9a-f]+)/ ;
	cdnkey = "my-cdn-key...................";
	if(!rFullPath.test(fullpath)){
		return false
	} ;
	var t=fullpath.match(rFullPath);
	var path=t[1],timestamp=t[2],rand=t[3],uid=t[4],md5=t[5]
	var timeDiff = Date.now()-timestamp;
	if(timeDiff>3600000){
		return false	
	}
	var data = path+"-"+timestamp+"-"+rand+"-"+uid+"-"+cdnkey;
	if (md5 == crypto.createHash('md5').update(data).digest("hex")){
		return decodeURI(path)
	};
	return false;
}

天下JS是一家,代码逻辑大部分从Node服务程序里面抠出来就直接可以用了。

就这样用NginScript简单复刻了腾讯云CDN的带校验静态文件分发。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档