nginx+lua脚本实现
1.nginx 配置
server {
listen 80;
server_name devops.test.com;
error_log /data/logs/nginx/error-devops.log;
location ^~ /proxy/ {
internal; #指定规则为internal规则,防止外部请求命中此规则
rewrite '^/proxy/(http?)/([^/]+)/(\d+)/(.*)' /$4 break;
proxy_pass $1://$2:$3;
}
location @client{
proxy_pass http://10.47.137.120:8001; #devops 服务地址及端口
}
location /api/v1{
proxy_pass http://10.47.137.120:8001; #devops 服务地址及端口
}
location /static{
proxy_pass http://10.47.137.120:8001;
}
location / {
access_by_lua_file 'conf/vhosts/lua/devops.lua';
}
}
1.从nginx的配置文件中能够看出,/api/v1/ 和/static 是没有调用lua脚本,而请求/ 都要走lua脚本认证html
/proxy/ 是lua脚本中使用的uri,主要是用来跳转到认证登陆平台
2.lua 脚本实现 devops.lua
local sso = 'http://sso.test.com'
local mysite = 'http://devops.test.com/'
local login_url = sso .. '?next=' .. mysitenginx
function Logout()
cookie_key = ngx.var.cookie_cookie_key
if cookie_key ~= nil then
local check_url = 'http/100.114.64.185/8000/logout/'
local checkSign = 'cookie_key='.. cookie_key
checkUrl = '/proxy/' .. check_url .. '?' .. checkSign
local res = ngx.location.capture(checkUrl, {
method = ngx.HTTP_GET,
})
ngx.redirect(login_url)
else
ngx.redirect(login_url)
end
end
function getSSOUser()
cookie_key = ngx.var.cookie_cookie_key
if cookie_key == nil then
ngx.redirect(login_url)
end
-- check user cookie
local check_url = 'http/100.114.64.185/8000/sso/' -- format used by ngx.location.capture && proxy_pass(a httpclient simulation)
local checkSign = 'cookie_key='.. cookie_key..'&&url='..mysite
checkUrl = '/proxy/' .. check_url .. '?' .. checkSign
--ngx.say(checkUrl)
local res = ngx.location.capture(checkUrl, {
method = ngx.HTTP_GET,
})
local cjson = require("cjson")
--ngx.say(res.body)
if 'false' == res.body then
ngx.redirect(login_url)
--ngx.say(res.body)
else
obj = cjson.decode(res.body)
user = obj['user']
return user
end
end
function doLogin()
local user = getSSOUser()
ngx.header['Set-Cookie'] = {'x_webauth_user =' .. user}
ngx.req.set_header("USER", user)br/>ngx.exec("@client")
end
if ngx.re.match(ngx.var.request_uri, "logout") then
ngx.header['Set-Cookie'] = {'x_webauth_user = false'}
Logout()
else
local x_user = ngx.var.cookie_x_webauth_user
local cookie_key = ngx.var.cookie_cookie_key
if cookie_key then
doLogin()
else
ngx.redirect(login_url)
end
endweb
最前面的三个local 是定义变量
if ngx.re.match(ngx.var.request_uri, "logout") then
ngx.header['Set-Cookie'] = {'x_webauth_user = false'}
Logout()
#判断请求的uri里面是否有“logout”,匹配则设置cookies的 x_webauth_user值
为false,并调用logout函数
3.若是uri不包括logout
local cookie_key = ngx.var.cookie_cookie_key 获取cookies下cookie_key的值
若是值为空,直接从定向到单点登陆,login_url为
http://sso.test.com?next=http://devops.test.com/ ,单点登陆平台须要作的
是获取next后面的uri及认证,认证成功以后,redis缓存cookie_key,
将cookie_key信息写入cookies中,让下次请求的时候带上cookie_key
4.若是cookie_key值存在,则调用认证函数doLogin()
function doLogin()
local user = getSSOUser() #调用getSSOUser 函数
ngx.header['Set-Cookie'] = {'x_webauth_user =' .. user}
ngx.req.set_header("USER", user)
ngx.exec("@client") #匹配nginx @client url
endredis
function getSSOUser() cookie_key = ngx.var.cookie_cookie_key if cookie_key == nil then ngx.redirect(login_url) end -- check user cookie local check_url = 'http/100.114.64.185/8000/sso/' -- format used by ngx.location.capture && proxy_pass(a httpclient simulation) local checkSign = 'cookie_key='.. cookie_key..'&&url='..mysite checkUrl = '/proxy/' .. check_url .. '?' .. checkSign --ngx.say(checkUrl) local res = ngx.location.capture(checkUrl, { method = ngx.HTTP_GET, }) #get请求单点登陆平台的接口/sso/cookie_key=* 验证cookie_key 的有效性,错误返回false local cjson = require("cjson") --ngx.say(res.body) if 'false' == res.body then #若是返回false,从新跳回登陆界面 ngx.redirect(login_url) --ngx.say(res.body) else obj = cjson.decode(res.body) user = obj['user'] return user #正确则返回认证用户及cookie信息写入 end
end
5.注销函数
function Logout()
cookie_key = ngx.var.cookie_cookie_key #获取cookie_key 值
if cookie_key ~= nil then #若是值不为空
local check_url = 'http/100.114.64.185/8000/logout/'
local checkSign = 'cookie_key='.. cookie_key
checkUrl = '/proxy/' .. check_url .. '?' .. checkSign
local res = ngx.location.capture(checkUrl, {
method = ngx.HTTP_GET,
}) #请求http://100.114.64.185:8000/logout/?cookie_key=****,经过get请求删除redis中的cookie值,达到注销的功能
ngx.redirect(login_url)
else
ngx.redirect(login_url)
end
end
6.http://100.114.64.185:8000 是一个阿里云内网负载均衡,后端是两台单点认证服务django