采用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); } }
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 '; } } }
2,自定义lua脚本