场景:
需要对图片服务器进行访问控制,只有app发起的请求才能访问
非app请求返回错误页面。
解决思路与方案:
与研发讨论后约定校验token,token中包含timestamp和基于timestamp按照一定规则
进行md5+盐值计算得到的key。server端使用nginx+lua校验token,不一致则返回错误页面
一.nginx+lua安装
1.安装luajit
tar -zxvf LuaJIT-2.0.5.tar.gz
cd LuaJIT-2.0.5
make && make install
vim /etc/profile
---------------------------------------------------------------------------------------------------------
export LUAJIT_LIB=/usr/local/lib
export LUAJIT_INC=/usr/local/include/luajit-2.0
---------------------------------------------------------------------------------------------------------
source /etc/profile
echo "/usr/local/lib" >> /etc/ld.so.conf
ldconfig
注:lib库路径一定记得加,否则后续安装引用时提示找不到
2.安装lua-nginx-module模块及依赖ngx_devel_kit
mv v0.3.1 ngx_devel_kit-0.3.1.tar.gz
tar -zxvf ngx_devel_kit-0.3.1.tar.gz -C /usr/local/src/
wget https://github.com/openresty/lua-nginx-module/archive/v0.10.9rc7.tar.gz
mv v0.10.9rc7.tar.gz lua-nginx-module-0.10.9.tar.gz
tar -zxvf lua-nginx-module-0.10.9.tar.gz -C /usr/local/src/
3.先决条件已ok,编译安装nginx
cd /usr/local/src/nginx-1.14.2/
./configure --with-stream --with-stream_ssl_preread_module --with-stream_ssl_module --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --add-module=/usr/local/src/nginx_upstream_check_module-master --add-module=/usr/local/src/nginx-sticky --with-pcre=/usr/local/src/pcre-8.38 --with-zlib=/usr/local/src/zlib-1.2.11 --add-module=/usr/local/src/ngx_devel_kit-0.3.1 --add-module=/usr/local/src/lua-nginx-module-0.10.9rc7
4.安装完毕后写个经典测试页验证,访问显示“hello,world”则nginx+lua安装成功
测试代码:
---------------------------------------------------------------------------------------------------------
location /lua {
set $test "hello,world";
content_by_lua '
ngx.header.content_type="text/plain";
ngx.say(ngx.var.test);
';
}
---------------------------------------------------------------------------------------------------------
二.安装md5模块(如只通过nginx调试,则直接使用ngx.md5(str)即可,就不需要安装这个模块)
tar -zxvf md5-1.3.tar.gz -C /usr/local/src/
放入模块路径中
cp lua/md5.lua /usr/share/lua/5.1/
三.直接上lua代码
vim /usr/local/nginx/lua/check.lua
---------------------------------------------------------------------------------------------------------
#!/usr/bin/lua
--获取url中的参数
local args = ngx.req.get_uri_args()
local token = tostring(args["token"])
--定义校验用key
local function getKey (timestamp,salt)
--根据timestamp里元素生成key,与研发约定一致即可,这里就不展示了
local value = ngx.md5(key)
return value
end
--拆解token中的key和timestamp
--x,y,z,w分别为截取位数,可自行设置
local tokenValue = ngx.decode_base64(token)
local keyValue = string.sub(tokenValue,x,y)
local timestamp = string.sub(tokenValue,z,w)
--salt盐值自行设置
local salt = "xxxx"
local checkValue = getKey(timestamp,salt)
if (keyValue ~= checkValue)then
ngx.redirect("/50x.html")
end
---------------------------------------------------------------------------------------------------------
遇到的坑:
ngx.decode_base64(str)这里处理的是字符,拿过来的参数token需要先 tostring
转换一下,否则error.log里有报错:报错内容如下
---------------------------------------------------------------------------------------------------------
2020/12/11 15:44:48 [error] 23948#0: *298 lua entry thread aborted: runtime error: /usr/local/nginx/lua/check.lua:21: string argument only
stack traceback:
coroutine 0:
[C]: in function 'decode_base64'
---------------------------------------------------------------------------------------------------------
四.nginx配置:
---------------------------------------------------------------------------------------------------------
location / {
rewrite_by_lua_file /usr/local/nginx/lua/check.lua;
root xxx;
index index.html index.htm;
}
---------------------------------------------------------------------------------------------------------
后记:
1.边看lua边写的代码,等待后续上生产看看情况,未知性能如何,参考思路即可,
具体代码自行斟酌,谨慎使用
2.一点感想:
工作也是一个不断学习的过程,而且这个学习是有着很强的目的和紧急性,来不及系统学习了先上车,很多场景都需要先解决问题,细节留待后续优化。后续使用会及时更新反馈,欢迎大家一起讨论。
参考链接: