採用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腳本