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