美文网首页
rewrite_by_lua或者access_by_lua不能修

rewrite_by_lua或者access_by_lua不能修

作者: 兔子Tony的主人 | 来源:发表于2018-08-26 10:06 被阅读0次

    准备用nginx + lua + redis解决的问题

    先不管注册登录的过程,假定已经登录。或者登录失效。前端每个请求,都要带上token令牌。
    然后nginx接到请求后,将请求交给lua处理,这个时候,lua根据有无token令牌,并且通过redis校验token令牌是否合法,然后用结果对nginx的一个变量进行赋值。
    然后nginx对这个变量进行判断,确定是跳转到登录页,还是返回请求需要的正确结果。
    当用这个思想去实现时,遇到了不可逾越的问题。问题如下

    问题

    查看了很多资料,如下代码应该是可以进入if判断的,但是我怎么调都不进if,代码如下

    location /test {
        set $a 12;
        set $b '';
        rewrite_by_lua 'ngx.var.b = tonumber(ngx.var.a) + 1';
        if ($b = '13') {
              echo "222";
        }
        #echo "res = $b";
    }
    
    

    这是,从网上找到的一段代码,按理,应该是可以输出222,这一串数字的。但是我的环境怎么试都不行
    心想,这lua要是不能修改nginx的变量,用lua岂不是很复杂了。觉得应该是自己的环境的问题。

    重新搭个环境

    历尽千辛万苦(其实不费事,嘿嘿),装好了一个centos虚机,开始安装OpenRestry
    安装的过程请点击此处查看另外一篇文章。
    但是,重新安装的虚机上,进行上述代码测试时,依然不能进入if内,输出222

    思考

    这个时候,我觉得,应该是if的代码和lua的代码不是同步的。才会导致这个问题。其实这个思路已经接近真相
    只是自己一直被一个问题困扰,既然lua不能这么玩,那要怎么玩呢。
    这之后一直在网上找资料。

    曙光

    在看了大量的资料后,有两个说法,我觉得是我解决问题的关键。

    • 1、rewrite_by_lua的功能描述,和字面意思的理解,都有跳转的意思,那么是不是可以rewrite_by_lua代码的内部就可以跳转呢?资料给予的答案是肯定的。
    • 2、不得不说网上关于lua的资料太少了,本该是一个大家都会跳的坑,愣是不能方便的搜索到解决方案。最终找到一份资料,确认了一个事实。nginx中的if会在rewrite_by_lua之前运行。至于echo为什么在rewrite_by_lua之后运行,并且输出被lua改变的变量值。还要后续进行深入的理解。这里不深入。

    转换思维

    其实,自己本身遇到这个问题,基于两点最根本的原因。

    • 1、对nginx+lua不熟悉
    • 2、已经有了实现登录状态处理的思维定式。顺着这个思维定式,注定要跳这个坑。

    所以,在一直思考lua不能这么玩,该怎么玩的同时,了解到nginx和lua的一些特性,最终迸发出新的处理方式。
    那就是,继续用rewrite_by_lua调用lua文件进行判断,只是,如果判断失效时,跳转到指定的登录页面,后续的nginx代码将被截断,不在执行。如果判断成功,则不进行任何处理,这样,当执行完lua文件后,自动继续nginx的处理,该反向代理就反向代理,该显示页面就显示页面。

    最终测试时成功的,这里贴上测试的代码,当然,正式环境的代码要复杂的多。

    • nginx.conf中的代码
    user  root;
    worker_processes  1;
    
    events {
        worker_connections  1024;
    }
    
    
    http {
        include       mime.types;
        default_type  application/octet-stream;
    
        sendfile        on;
    
        keepalive_timeout  65;
    
        lua_code_cache off;
    
        server {
            listen      80;
            server_name localhost;
            location / {
                root    html;
                index   index.html index.htm;
            }
            error_page  500 502 503 504  /50x.html;
            location = /50x.html {
                root    html;
            }
            location ^~ /api {
                #在代理之前判断是否为有效登录
                rewrite_by_lua_file "/usr/local/openresty/nginx/conf/loginresult";
                #如果在rewrite_by_lua中没有跳转或者返回,则会运行下边的反向代理。
                proxy_pass http://127.0.0.1:8095;
            }
        }
    }
    
    • loginresult文件中的代码
    --接收access_token判断是否登录
    local login_token = ngx.var.http_access_token
    local login_user = ngx.var.http_user_name
    
    local cjson = require("cjson")
    
    local redis = require "resty.redis"
    local red = redis:new()
    
    red:set_timeout(1000) --  1 sec
    
    local ok, err = red:connect("127.0.0.1", 6379)
    if not ok then
            ngx.say(cjson.encode({code = 500,message = "错误编号***,请联系系统维护人员进行处理!"}))
    end
    
    local result, err = red:get(login_token)
    
    if not result then
        local loginfailobj = {code = 500,message = "no login"}
        local loginfailjson = cjson.encode(loginfailobj)
        ngx.say(loginfailjson)
    end
    --如果存在登录信息,并且正确,则重新设定缓存存在时间,代码将来写在下边。
    
    local ok, err = red:close()
    

    结语:伴随着每一个困难问题的攻克,都会带给我愉悦的心情,这是我走在开发路上,前进的动力。

    相关文章

      网友评论

          本文标题:rewrite_by_lua或者access_by_lua不能修

          本文链接:https://www.haomeiwen.com/subject/anggiftx.html