採用lua指令碼獲取mysql、redis資料以及jwt的校驗
阿新 • • 發佈:2021-02-27
一、安裝配置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指令碼