简介
通过3种方法(nginx/php/nginx+php)来对视频点播VOD做权限控制。
Github项目地址
部署
✅ 需要安装 Git, Docker, Docker-compose
1 2 3 4 5 6
| $ git clone https://github.com/copriwolf/vod-authority-control-demo.git $ cd vod-authority-control-demo
$ docker-compose up
|
测试
- 添加hosts
127.0.0.1 local.video-demo.com
- 浏览器地址
http://local.video-demo.com
- 有3种鉴定方法可以选择(php/nginx/php+nginx)
- 如果你想正常播放,追加
?token=anyWordYouWant
到url尾部,形如 local.video-demo.com/php-auth/?token=XXX
核心实现
Nginx方法
使用了nginx-mod-http-lua
模块,使用了lua语言在nginx的配置文件中对视频文件进行了权限校验
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| location ~ .*\.(mp4|flv|avi)$ { content_by_lua_block { local args, err = ngx.req.get_uri_args()
local token = args.token local key = args.key
if key == nil or token == nil then ngx.exit(ngx.HTTP_FORBIDDEN) end
if token ~= ngx.md5(key) then ngx.exit(ngx.HTTP_FORBIDDEN) end
return ngx.exec("@ok") } }
location @ok { default_type 'video/mp4'; }
|
使用该方法,
好处:部署非常快,不需要额外的php支持;
坏处:开发调试比较麻烦,每次改完conf文件都需要$ nginx -s reload
,对于没有nginx操作权限的开发比较苦恼。
PHP方法
直接在代码内编写一个校验函数逻辑
1 2 3 4 5 6 7 8 9
| function checkAuth() { $token = $_GET['token']; if (!$token) { echo 'token is null'; exit; } } checkAuth();
|
通过后再进行视频协议的转发
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| function GetMp4File($file) { $size = filesize($file); header("Content-type: video/mp4"); header("Accept-Ranges: bytes"); if (isset($_SERVER['HTTP_RANGE'])) { header("HTTP/1.1 206 Partial Content"); list($name, $range) = explode("=", $_SERVER['HTTP_RANGE']); list($begin, $end) =explode("-", $range); if ($end == 0) { $end = $size - 1; } } else { $begin = 0; $end = $size - 1; } header("Content-Length: " . ($end - $begin + 1)); header("Content-Disposition: filename=".basename($file)); header("Content-Range: bytes ".$begin."-".$end."/".$size); $fp = fopen($file, 'rb'); fseek($fp, $begin); while (!feof($fp)) { $p = min(1024, $end - $begin + 1); $begin += $p; echo fread($fp, $p); } fclose($fp); } GetMp4File("../demo.mp4");
|
使用该方法,
好处:php代码简单易用,而且不需要特意配置nginx配置;
坏处:由于每次请求都是php去读取视频文件,会导致请求瞬间占用大量CPU,内存。
Nginx+PHP方法
我们把逻辑验证代码写在PHP,但是让Nginx来控制资源的读取,有利于降低CPU与内存的消耗。
首先我们会在Nginx通过nginx-mod-http-lua
模块来转发token和key到PHP处理。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| location @nginx_verify_with_php { content_by_lua_block { local verify_url = "/nginx-auth-with-php/verify/"
res = ngx.location.capture(verify_url, { args = ngx.req.get_uri_args()})
if res.status ~= 200 or res.body ~= "ok" then ngx.exit(ngx.HTTP_FORBIDDEN) end
ngx.exec("@ok") } }
|
同时,我们把验证代码放在PHP中,可以更为灵活的修改验证算法。(不再需要改一次就要在终端运行nginx -s reload
来让配置生效)
1 2 3 4 5 6 7 8 9 10 11 12
| <?php function verify($args) { if ($args['token']) { return 'ok'; } }
$check = verify($_REQUEST) ? 'ok' : 'failed'; echo $check; exit;
|
使用该方法,
好处:使用Nginx控制权限入口,PHP做具体鉴权逻辑,分离了职责后更为灵活,部署后修改验证算法更简单容易;
坏处:需要同时配置好Nginx以及PHP的环境与联动。