• 采用lua脚本获取mysql、redis数据以及jwt的校验


    一、安装配置Openresty

    1,安装

    wget https://openresty.org/download/ngx_openresty-1.9.7.1.tar.gz   # 下载
    tar xzvf ngx_openresty-1.9.7.1.tar.gz       # 解压
    cd ngx_openresty-1.9.7.1/ 
    ./configure
    make 
    make install

    2,配置nginx.conf

      按照上一步安装的默认路径为:/usr/local/openresty/nginx/conf 中。

    worker_processes  1;
    #配置日志级别为info存放在logs/error.log中
    error_log  logs/error.log  info;
    events {
        worker_connections  1024;
    }
    http {
        include       mime.types;
        default_type  application/octet-stream;
        sendfile        on;
        keepalive_timeout  65;
    
        #配置lua脚本,包括/usr/local/openresty/nginx/lua/?.lua自定义脚本位置
        lua_package_path "/usr/local/openresty/lualib/?.lua;/usr/local/openresty/nginx/lua/?.lua;;";
        lua_package_cpath "/usr/local/openresty/lualib/?.so;;";
    
        server {
            listen       80;
            server_name  localhost;
    
            location / {
                root   html;
                index  index.html index.htm;
            }
        }
    }

    二、lua读取Mysql中数据

    1,编写lua脚本

      存储地址(nginx中能加载的路径)为: /usr/local/openresty/nginx/lua

    --指定文本输出的文件类型为json类型
    ngx.header.content_type="application/json;charset=utf-8"
    --引入库文件json
    local cjson = require "cjson"
    --引入依赖库mysql
    local mysql = require "resty.mysql"
    
    --配置数据库连接信息
    local props = {
            host = "127.0.0.1",
            port = 3306,
            database = "test",
            user = "root",
            password = "123456"
    }
    
    --创建连接、设置超时时间、编码格式
    local db,err = mysql:new()
    
    db:set_timeout(10000)
    db:connect(props)
    db:query("SET NAMES utf8")
    
    --SQL语句 (读取参数中id的值)
    local id = ngx.req.get_uri_args()["id"]
    local sql = "select * from t_user where id="..id
    
    ngx.log(ngx.INFO,"sql语句为:",sql)
    
    --执行SQL语句
    res, err, errno, sqlstate = db:query(sql)
    
    --关闭连接
    db:close()
    --响应数据->json ngx.say(cjson.encode(res))

    2,配置nginx读取lua脚本

      在nginx.conf的server中添加

    #配置mysql
    location /mysql {        
        content_by_lua_file /usr/local/openresty/nginx/lua/mysql.lua;
    }

    3,启动openresty

      如果配置了/etc/profile的环境变量,直接使用命令:nginx 或 nginx -s reload

    三、lua操作redis(单机)

    1,编写lua脚本

    a)redis_basic.lua

    local redis = require "resty.redis"
    
    local config = {
        host = "127.0.0.1",
        port = 6379,
        pass = "123456"  -- redis 密码,没有密码的话,把这行注释掉
    }
    
    local _M = {}
    
    function _M.new(self)
        local red = redis:new()
        red:set_timeout(1000) -- 1 second
        local res = red:connect(config['host'], config['port'])
        ngx.log(ngx.INFO,"red的连接为::",res)
        if not res then
            return nil
        end
        if config['pass'] ~= nil then
            res = red:auth(config['pass'])
            if not res then
                return nil
            end
        end
        red.close = close
        return red
    end
    
    local function close(self)
        local sock = self.sock
        if not sock then
            return nil, "not initialized"
        end
        if self.subscribed then
            return nil, "subscribed state"
        end
        return sock:setkeepalive(10000, 50)
    end
    
    return _M

    b)redis.lua

    --定义redis操作的封装
    local redis_basic = require "redis_basic"
    
    --定义一个模块
    local lredis={}
    
    --定义一个方法,Redis集群增加数据、查询数据、删除数据
    --增加数据
    function lredis.set(key,val)
            local red = redis_basic:new()
            red:set(key,val)
            red:close()
    end
    
    --根据key查询数据
    function lredis.get(key)
            local red = redis_basic:new()
            local value = red:get(key)
            red:close()
            --返回数据
            return value
    end
    
    --根据key删除数据
    function lredis.del(key)
            local red = redis_basic:new()
            red:del(key)
            red:close()
    end
    
    return lredis

    2,配置nginx读取lua脚本

      在nginx.conf的server中添加

    #配置redis
    location /redis {
        content_by_lua '
        --指定文本输出的文件类型为json类型
        ngx.header.content_type="application/json;charset=utf-8"
        --引入redis.lua脚本库
        local cjson = require "cjson"
        --在http中配置了相应的lua读取地址,这里实际是读取/usr/local/openresty/nginx/lua/redis.lua
        local rredis = require "redis"
        
        --获取前端操作数据 key value method=1(增加) 2(修改) 3(删除)
        local args = ngx.req.get_uri_args()
        local key = args["id"]
        local value = args["value"]
        local method = args["method"]
    
        --根据method的值执行不同操作
        if method == "1" then
            ngx.log(ngx.INFO,"接收的key为:",key)
            ngx.log(ngx.INFO,"接收的val为:",value)
            --增加数据
            rredis.set(key,value)
            --响应数据
            ngx.say("set success!")
        elseif method=="2" then
            --执行查询
            local result = rredis.get(key)
            ngx.say(cjson.encode(result))
        else
            --删除
            rredis.del(key)
            ngx.say("del success!")
        end
         ';
    }

    3,启动openresty

      如果配置了/etc/profile的环境变量,直接使用命令:nginx 或 nginx -s reload

    4,测试

    #添加数据
    http://hadoop103/redis?method=1&id=key&value=111
    #查询数据
    http://hadoop103/redis?method=2&id=key
    #删除数据
    http://hadoop103/redis?method=3&id=key

    四、lua完成jwt的校验

    1,添加jwt的脚本

      拷贝github中的lua脚本到本地'/usr/local/openresty/lualib/resty'中:

    #拷贝文件为hmac.lua 到 /usr/local/openresty/lualib/resty
    https://github.com/jkeys089/lua-resty-hmac/blob/master/lib/resty/hmac.lua
    #拷贝文件为evp.lua jwt-validators.lua 和 jwt.lua 到 /usr/local/openresty/lualib/resty
    https://github.com/SkyLothar/lua-resty-jwt/tree/master/lib/resty

      

    2,编写lua脚本

    a)jwt_token

    --引入依赖库
    local jwt = require "resty.jwt"
    
    --定义一个模块
    local jwttoken={}
    
    --定义一个校验jwt令牌的方法
    --auth_token:令牌 Bearer XXXdsafaf
    --secret: 密钥
    function jwttoken.check(auth_token,secret)
        --校验格式,去掉'Bearer '
        local _,_,token=string.find(auth_token,"Bearer%s+(.+)")
        
        --通过jwt模块校验令牌
        local result = jwt:verify(secret,token)
        
        return result
    end
    
    return jwttoken

    b)jwt_check

    --调用jwt_token.lua中的令牌校验方法
    ngx.header.content_type="application/json;charset=utf-8"
    
    --引入依赖库,根据文件名
    local jwttoken = require "jwt_token"
    --引入json依赖库
    local cjson = require "cjson"
    
    --响应数据
    local response = {}
    
    --获取请求头中的令牌
    local auth_token = ngx.var.http_Authorization
    
    --准备密钥
    local secret = "5pil6aOO5YaN576O5Lmf5q+U5LiN5LiK5bCP6ZuF55qE56yR"
    
    --调用校验方法
    local result = jwttoken.check(auth_token,secret)
    
    --组装响应结果
    response["code"]=200
    response["body"]=result
    response["message"]="完成校验,请查看body校验结果!"
    
    ngx.say(cjson.encode(response))

    3,配置nginx读取lua脚本

      在nginx.conf的server中添加

    #配置jwt
    location /jwt {
         content_by_lua_file /usr/local/openresty/nginx/lua/jwt_check.lua;
    }

    4,配置java生成jwt

    a)添加maven依赖

    <dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt</artifactId>
        <version>0.6.0</version>
    </dependency>

    b)添加java生成代码

    import io.jsonwebtoken.JwtBuilder;
    import io.jsonwebtoken.Jwts;
    import io.jsonwebtoken.SignatureAlgorithm;
    
    import javax.crypto.spec.SecretKeySpec;
    import java.security.Key;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.HashMap;
    import java.util.Map;
    
    public class JWTDemo {
    
        public static final String SECRET="5pil6aOO5YaN576O5Lmf5q+U5LiN5LiK5bCP6ZuF55qE56yR";
    
        public static String createJWT(String uid, long ttlMillis) throws Exception {
            SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
            long nowMillis = System.currentTimeMillis();
            Date now = new Date(nowMillis);
            Key signingKey = new SecretKeySpec(SECRET.getBytes(), signatureAlgorithm.getJcaName());
    
            Map<String,Object> header=new HashMap<String,Object>();
            header.put("typ","JWT");
            header.put("alg","HS256");
            JwtBuilder builder = Jwts.builder().setId(uid)
                    .setIssuedAt(now)
                    .setIssuer(uid)
                    .setSubject(uid)
                    .setHeader(header)
                    .signWith(signatureAlgorithm, signingKey);
            if (ttlMillis >= 0) {
                long expMillis = nowMillis + ttlMillis;
                Date exp = new Date(expMillis);
                System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(exp));
                builder.setExpiration(exp);
            }
            return builder.compact();
        }
    
        public static void main(String[]cmd) throws Exception {
            String s=createJWT("yaya",36000000);
            System.out.println("Bearer "+s);
        }
    
    }
    View Code

    5,测试验证效果

      

    五、总结

    1,nginx.conf配置

    worker_processes  1;
    
    #error_log  logs/error.log;
    #error_log  logs/error.log  notice;
    error_log  logs/error.log  info;
    
    #pid        logs/nginx.pid;
    
    
    events {
        worker_connections  1024;
    }
    
    
    http {
        include       mime.types;
        default_type  application/octet-stream;
        lua_shared_dict redis_cluster_slot_locks 100k;
    
        sendfile        on;
    
        keepalive_timeout  65;
    
        #配置lua脚本,包括lua/?.lua自定义脚本位置
        lua_package_path "/usr/local/openresty/lualib/?.lua;/usr/local/openresty/nginx/lua/?.lua;;";
        lua_package_cpath "/usr/local/openresty/lualib/?.so;;";
    
        server {
            listen       80;
            server_name  localhost;
    
    
            location / {
                root   html;
                index  index.html index.htm;
            }
    
        #配置mysql
        location /mysql {
             content_by_lua_file /usr/local/openresty/nginx/lua/mysql.lua;
        }
        
        #配置jwt
        location /jwt {
             content_by_lua_file /usr/local/openresty/nginx/lua/jwt_check.lua;
        }
    
        #配置redis
        location /redis {
             content_by_lua '
            --指定文本输出的文件类型为json类型
            ngx.header.content_type="application/json;charset=utf-8"
            --引入redis.lua脚本库
            local cjson = require "cjson"
            --在http中配置了相应的lua读取地址,这里实际是读取/usr/local/openresty/nginx/lua/redis.lua
            local rredis = require "redis"
            
            --获取前端操作数据 key value method=1(增加) 2(修改) 3(删除)
            local args = ngx.req.get_uri_args()
            local key = args["id"]
            local value = args["value"]
            local method = args["method"]
    
            --根据method的值执行不同操作
            if method == "1" then
                ngx.log(ngx.INFO,"接收的key为:",key)
                ngx.log(ngx.INFO,"接收的val为:",value)
                --增加数据
                rredis.set(key,value)
                --响应数据
                ngx.say("set success!")
            elseif method=="2" then
                --执行查询
                local result = rredis.get(key)
                ngx.say(cjson.encode(result))
            else
                --删除
                rredis.del(key)
                ngx.say("del success!")
            end
             ';
        }
        }
    }
    View Code

    2,自定义lua脚本

      

  • 相关阅读:
    BZOJ 2565 最长双回文串 (Manacher)
    BZOJ 3881 [COCI2015]Divljak (Trie图+Fail树+树链的并+树状数组维护dfs序)
    BZOJ 3530 [SDOI2014]数数 (Trie图/AC自动机+数位DP)
    BZOJ 1444 [JSOI2009]有趣的游戏 (Trie图/AC自动机+矩阵求逆)
    BZOJ 1195 [HNOI2006]最短母串 (Trie图+状压+bfs最短路)
    luogu P5289 [十二省联考2019]皮配
    luogu P5285 [十二省联考2019]骗分过样例
    luogu P5294 [HNOI2019]序列
    luogu P5292 [HNOI2019]校园旅行
    luogu P5284 [十二省联考2019]字符串问题
  • 原文地址:https://www.cnblogs.com/bbgs-xc/p/14437703.html
Copyright © 2020-2023  润新知