您的位置:首页 > 运维架构 > Nginx

nginx+lua实现登陆验证

2018-02-23 17:22 429 查看
用于在多台服务器上单点登录SSO、无SESSION,用户身份的验证。
1、安装lua

yum install readline.x86_64 readline-devel.x86_64

wget http://www.lua.org/ftp/lua-5.1.5.tar.gz
make linux

make install

注意:不要使用5.2版本,5.2版本的lua和nginx的整合有问题,编译会报错:

LUA_GLOBALSINDEX' undeclared (first use in this function)

参考:https://github.com/LuaLanes/lanes/issues/18

2、编译nginx
下载lua-nginx-module

wget https://github.com/chaoslawful/lua-nginx-module/zipball/master
file master

unzip master

mv chaoslawful-lua-nginx-module-06d654b/ lua-nginx-module

下载ngx_devel_kit
https://github.com/simpl/ngx_devel_kit/zipball/master
file master

unzip master

mv simpl-ngx_devel_kit-4192ba6/ simpl-ngx_devel_kit

编译nginx

tar -xvzf nginx-1.2.1.tar.gz

./configure \

--prefix=/usr/local/nginx \

--with-http_stub_status_module \

--without-poll_module \

--without-select_module \

--with-http_ssl_module \

--with-http_realip_module \

--with-http_perl_module \

--add-module=../simpl-ngx_devel_kit \

--add-module=../lua-nginx-module

make 
make install

2、测试lua

测试

location = /lua {

content_by_lua '

ngx.say("Hello, Lua!")

';

}

3、登录验证
nginx添加配置

access_by_lua_file 'conf/access.lua';

access.lua:
可以根据需要添加更多的验证域

local secretkey='1234567890abcdefghi'

if ngx.var.cookie_uid == nil or ngx.var.cookie_token == nil
then

ngx.req.set_header("Check-Login", "NULL")

return

end

--local ctoken = ngx.md5('uid:' .. ngx.var.cookie_uid ..
'&secretkey:' .. secretkey)

local ctoken = ngx.md5(ngx.var.cookie_uid .. secretkey)

if ctoken == ngx.var.cookie_token then

ngx.req.set_header("Check-Login",
"YES")

else

ngx.req.set_header("Check-Login", "NO")

end

return

如果uid+lua中的securekey的md5值和请求中的cookie的值一致,则设置request
header中的HTTP_CHECK_LOGIN为YES,否则为No,如果不存在uid或token这两个cookie中的一个,则HTTP_CHECK_LOGIN设置为NULL。

关于Check-Login,HTTP_CHECK_LOGIN:
lua中设置的heaer为Check-Login,输出后就变成了HTTP_CHECK_LOGIN,即前面加了HTTP_,经过测试,有些会添加HTTP_,而有些则不会添加,如Content-Type。

详细信息查看:http://wiki.nginx.org/HttpLuaModule#ngx.req.set_header

4、测试
使用perl cgi
perl打印ENV

#!/usr/bin/perl -w

use strict;

use CGI;

use Data::Dumper;

my $query = new
CGI;

print $query->header('text/html');

print Dumper \%ENV;

#if ($ENV{HTTP_CHECK_LOGIN} ne "YES"){

# print "not
auth";

# exit;

#}

打印\%ENV哈希可以看到我们添加的header。

注释部分是一个例子,针对认证的结果做更多的操作。

可以使用curl来带着cookie进行测试:
curl -b
"uid=1234;token=8323d8c4a0533dc78c7051a074cdb286" http://127.0.0.1/7.cgi 
如果使用echo
打印md5值,需要使用-n参数去掉回车
echo -n 123456789|md5sum

如何查看lua生成的md5?

 
      location =
/lua {
 
     
    content_by_lua '
 
     
     
   local ctoken = ngx.md5("12345"
.. "6789")
 
     
     
  ngx.say(ctoken)  
    
 
     
    ';
 
      }

关于查看access.lua生成的cookie

local secretkey='cookiesecretKey'

if ngx.var.cookie_uid == nil or ngx.var.cookie_token == nil
then

ngx.req.set_header("Check-Login", "NULL")

return

end

--local ctoken = ngx.md5('uid:' .. ngx.var.cookie_uid ..
'&secretkey:' .. secretkey)

local ctoken = ngx.md5(ngx.var.cookie_uid .. secretkey)

if ctoken == ngx.var.cookie_token then

ngx.req.set_header("Check-Login", "YES")

print (ctoken)

print (ngx.var.cookie_token)

else

ngx.req.set_header("Check-Login", "NO")

print (ctoken)

print (ngx.var.cookie_token)

end

return

打开nginx的log到debug,从error里可以看到access.lua的输出

通过html种植cookie

<</span>html xmlns="http://www.w3.org/1999/xhtml">

<</span>head>

<</span>meta http-equiv="Content-Type" content="text/html;
charset=gbk">

<</span>/head>

<</span>body>

<</span>p>

<</span>script>

document.cookie="domain=intercom.com.cn"; 

document.cookie="uid=1234"; 

document.cookie="token=dbd19902c04fdc68ee8b97510f454614"; 

//document.cookie="expires=Sat,
31-Dec-39 23:59:59 GMT"; 

document.write(document.cookie); 

<</span>/script>

<</span>/p>

<</span>/body>

<</span>/html>

转自:http://blog.chinaunix.net/uid-1838361-id-3271391.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: