打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
ngx_lua实现登录逻辑

最近在公司做一个简单的portal,本来很简单的,只用ngx_lua就可以实现所有的业务逻辑,不需要upstream上游服务。但被要求接入公司内部的用户校验系统,说白了就是一个登录过程,只允许公司内部的用户可以登录访问。

公司内部有一整套组件,只要在业务代码里嵌入改组件,就能自动检测用户是否已经登录、或session是否过期,是则跳转到登录界面,用户输入密码验证后,重新跳转会原始访问的页面。

但公司提供的组件都是基于常用的业务语言的,如php、java,我也不想再加上这些玩意,于是考虑用ngx_lua实现这样一套登录逻辑。下面是一个测试配置,基本总结了nginx中实现登录的方法。

    lua_shared_dict stats 10m;        init_by_lua '                local stats = ngx.shared.stats                stats:set("flag",1)        ';    server {                listen 80 so_keepalive=on;                set $flag 0;                rewrite_by_lua '                        local stdo = string.match(ngx.var.uri, "(%a+%.do)")                        if stdo == nil then                                local res = ngx.location.capture("/isLoginExpired.do")                                ngx.var.flag = res.body                        end                ';                location /isLoginExpired.do {                        content_by_lua '                                local stats = ngx.shared.stats                                local flag = stats:get("flag")                                ngx.print(flag)                        ';                }        location / {                  content_by_lua '                        if ngx.var.flag == "1" then                                local query = "backuri="..ngx.var.request_uri                                query = string.gsub(query,"&","%%26")                                return ngx.redirect("/redirect?"..query, 302)                         else                                local new_uri = "/fcgi"..ngx.var.request_uri                                ngx.exec("/fcgi")                        end                  ';        }                location /redirect {                        content_by_lua '                                local stats = ngx.shared.stats                --      do login or update cookies, and then flag=0                                stats:set("flag",0)                                local backuri = ngx.var.arg_backuri                                return ngx.redirect(backuri, 302)                        ';                }                location /fcgi {                        content_by_lua '                                ngx.say(ngx.var.request_uri)                                ngx.say("come into fcgi")                                ngx.say(ngx.var.flag)                                ngx.say(ngx.var.right)                        ';                 }    }

 

这里用共享内存 stats:flag模拟是否登录的标志位,初始为1,表示未登录。

对于所有请求,首先用一段rewrite_by_lua代码来判断是否登录,这里主要就是查看stats:flag的值,其中可以利用ngx_lua提供的强大的子请求功能。这里要注意的是,所用子请求的uri一定要排除在要判断登录态请求之外(即该/isLoginExpired.do请求不能再去判断登录态,否则会造成死循环)。

之后所有请求进入 location / {...},这里主要利用前面判断的结果(ngx.var.flag的值,不要和那个stats:flag混淆了,名字没起好),没有登录,则利用ngx.redirect()做302跳转,跳转到登录界面,用户可以输入密码,这里简单的模拟了一下,直接把stats:flag置0,并且添加query语句,带上backuri字段。

一般登录应用中,都会读取backuri字段,登录认证后,重新302到该backuri。例子中的location /redirect {...} 就是模拟了这样一个登录应用。

请求重新来之后,进入location / {...}, 判断已登录,则通过ngx.exec()直接内部跳转到具体的业务location。

 

一开始的时候还是觉得比较绕的,理清楚之后还是比较简洁的,这里面用到ngx_lua的几个强大的功能,也是一次很好的实践

ngx.location.capture()    子请求

ngx.redirect()        等同于nginx原生的rewrite .. .. redirect (302跳转)

ngx.exec()           等同于nginx原生的rewrite .. .. break (内部跳转)

 

运行结果如下

 

 

不当之处,欢迎指正

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
第二章 Nginx+Lua开发入门
通过nginx配置文件抵御攻击,防御CC攻击的经典思路! | moon's blog
fastdfs支持缩略图
nginx+lua_nginx+GraphicsMagick生成实时缩略图
Docker+DockerCompose封装web应用的方法步骤
第八章 流量复制/AB测试/协程
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服