1铁材、docker下安裝Kong
1.1 創(chuàng)建一個自定義網(wǎng)絡(luò)挫以,用來允許容器之間的通信
dockernetworkcreatekong-net
1.2 通過docker-compose的方式安裝
version: "3.7"
services:
# kong 管理界面
? konga:
? ? image: pantsel/konga
? ? environment:
? ? - "TOKEN_SECRET=51liveup.cn"
? ? - "NODE_ENV=production"
? ? ports:
? ? - 1337:1337
? ? networks:
? ? - kong-net
? ? depends_on:
? ? ? - kong-database
# 數(shù)據(jù)庫服務(wù)
? kong-database:
? ? image: postgres:9.6
? ? ports:
? ? ? - "5432:5432"
? ? environment:
? ? # 訪問數(shù)據(jù)庫的用戶
? ? ? - "POSTGRES_USER=kong"
? ? ? - "POSTGRES_DB=kong"
? ? ? - "POSTGRES_HOST_AUTH_METHOD=trust"
? ? networks:
? ? ? - kong-net
? ? volumes:
? ? # 同步時間
? ? ? # - /etc/localtime:/etc/localtime:ro
? ? # 數(shù)據(jù)庫持久化目錄
? ? ? - ./data/postgresql:/var/lib/postgresql/data
? kong:
? ? ? # 鏡像版本,目前最新
? ? ? image: kong:latest
? ? ? environment:
? ? ? # 數(shù)據(jù)持久化方式辜王,使用postgres數(shù)據(jù)庫
? ? ? - "KONG_DATABASE=postgres"
? ? ? # 數(shù)據(jù)庫容器名稱,Kong連接數(shù)據(jù)時使用些名稱
? ? ? - "KONG_PG_HOST=kong-database"
? ? ? # 數(shù)據(jù)庫名稱
? ? ? - "KONG_CASSANDRA_CONTACT_POINTS=kong-database"
? ? ? # 日志記錄目錄
? ? ? - "KONG_PROXY_ACCESS_LOG=/dev/stdout"
? ? ? - "KONG_ADMIN_ACCESS_LOG=/dev/stdout"
? ? ? - "KONG_PROXY_ERROR_LOG=/dev/stderr"
? ? ? - "KONG_ADMIN_ERROR_LOG=/dev/stderr"
? ? ? # 暴露的端口
? ? ? - "KONG_ADMIN_LISTEN=0.0.0.0:8001, 0.0.0.0:8444 ssl"
? ? ? ports:
? ? ? - 8000:8000
? ? ? - 8443:8443
? ? ? - 8001:8001
? ? ? - 8444:8444
? ? ? # 使用docker網(wǎng)絡(luò)
? ? ? networks:
? ? ? - kong-net
? ? ? # 依賴數(shù)據(jù)庫服務(wù)
? ? ? depends_on:
? ? ? ? - kong-database
? ? ? volumes:
? ? ? # 數(shù)據(jù)庫持久化目錄
? ? ? ? - ./data/kong:/data
networks:
? kong-net:
? ? external: true
1.3 執(zhí)行docker-compose up 之后熄攘,會發(fā)現(xiàn)postgres連接不上勤哗,這個時候再初始化postgres數(shù)據(jù)庫即可
dockerrun--rm\--network=kong-net\-e"KONG_DATABASE=postgres"\-e"KONG_PG_HOST=kong-database"\-e"KONG_CASSANDRA_CONTACT_POINTS=kong-database"\kong:latestkongmigrationsbootstrap
1.4 一定要在創(chuàng)建數(shù)據(jù)庫容器之后于样,并且保持?jǐn)?shù)據(jù)庫的Docker容器在運行狀態(tài)疏叨,再執(zhí)行初始化數(shù)據(jù)庫,數(shù)據(jù)庫初始化成功后穿剖,再次使用docker-compose up -d 啟動服務(wù)就可以了
1.5 安裝成功之后蚤蔓,訪問http://127.0.0.1:8001或者curl命令查看,出現(xiàn)如下效果即是安裝成功
curl-ihttp://localhost:8001/
2携御、Konga可視化界面體驗
2.1 創(chuàng)建登錄賬號
2.2 登錄賬號
2.3 連接docker環(huán)境中的kong
2.4 連接成功
3、Kong基礎(chǔ)功能體驗
3.1 以伊的家小程序商城列表數(shù)據(jù)為例既绕,創(chuàng)建一個商品列表的路由服務(wù)
3.2.1以命令行方式創(chuàng)建一個Services
curl-i-XPOST\--urlhttp://localhost:8001/services/ \--data'name=kong-service'\--data'url=http://api-mall-admin.yidejia.com'
3.2.2 以Result Api方式創(chuàng)建一個Services
3.2.3 以Konga方式創(chuàng)建一個Services
3.3以命令行方式創(chuàng)建一個路由
curl-i-XPOST\--urlhttp://localhost:8001/services/kong-service/routes \--data'hosts[]=www.kong.com'
3.4 校驗curl創(chuàng)建的服務(wù)跟路由
curl-i-XGET\--urlhttp://localhost:8000/api/admin/goods \--header'Host: www.kong.com'
出現(xiàn)如下效果即是創(chuàng)建成功
宿主機(jī)訪問的話啄刹,需要額外增加hosts配置? 127.0.0.1 www.kong.com
4、Kong插件體驗
使用Kong自帶的key-auth插件
4.1.1 以命令行方式使用一個插件
curl-i-XPOST\--urlhttp://localhost:8001/services/kong-service/plugins/ \--data'name=key-auth'
4.1.2 以Konga方式使用插件
4.1.3 查看訪問效果
出現(xiàn)如下頁面凄贩,即是插件生效
4.2.1以命令行方式創(chuàng)建一個消費者
curl-i-XPOST\--urlhttp://localhost:8001/consumers/ \--data"username=JyPony"
4.2.2 以Konga方式創(chuàng)建一個消費者
4.3.1以命令行方式為消費者創(chuàng)建一個key值
curl-i-XPOST\--urlhttp://localhost:8001/consumers/JyPony/key-auth/ \--data'key=123456'
4.3.2以Konga方式為消費者創(chuàng)建一個key值
4.4.1 再次訪問http請求誓军,出現(xiàn)如下效果,即是訪問成功(Kong Error 報錯消失了)
5疲扎、Kong插件自定義開發(fā)(Ascii參數(shù)校驗示例)
5.1 基本插件模塊和高級插件模塊
5.2 創(chuàng)建項目昵时,其中assci必須要插件名稱
5.3 最簡單的插件模塊必須包含handler.lua文件跟schema.lua文件
handler.lua文件示例如下:
localipmatcher=require"resty.ipmatcher"localngx=ngxlocalkong=konglocalerror=errorlocalAsciiHandler={PRIORITY=990,VERSION="2.0.0",}localfunctionmatch_bin(list,binary_remote_addr)localip,err=ipmatcher.new(list)iferrthenreturnerror("failed to create a new ipmatcher instance: "..err)endlocalis_matchis_match,err=ip:match_bin(binary_remote_addr)iferrthenreturnerror("invalid binary ip address: "..err)endreturnis_matchend--判斷table是否為空localfunctionisTableEmpty(t)returnt==nilornext(t)==nilend--兩個table合并localfunctionunion(table1,table2)fork,vinpairs(table2)dotable1[k]=vendreturntable1end--檢驗請求的sign簽名是否正確--params:傳入的參數(shù)值組成的table--secret:項目secret,根據(jù)key找到secretlocalfunctionsignCheck(params,secret,binary_remote_addr,allow,deny)ifallowand#allow > 0 thenlocalallowed=match_bin(allow,binary_remote_addr)ifallowedthenlocalmess="白名單ip"returntrue,messendendifdenyand#deny > 0 thenlocalblocked=match_bin(deny,binary_remote_addr)ifblockedthenlocalmess="黑名單ip"returnfalse,messendend--判斷參數(shù)是否為空椒丧,為空報異常ifisTableEmpty(params)thenlocalmess="參數(shù)為空"returnfalse,messendifsecret==nilthenlocalmess="私鑰為空"returnfalse,messend--判斷是否有簽名參數(shù)localsign=params["sign"]ifsign==nilthenlocalmess="簽名參數(shù)為空"returnfalse,messend--是否存在時間戳的參數(shù)localtimestamp=params["time"]iftimestamp==nilthenlocalmess="時間戳參數(shù)為空"returnfalse,messend--時間戳過期時間校驗,10秒鐘校驗localnow_mill=ngx.now()*1000--毫秒級ifnow_mill-(timestamp*1000)>10000thenlocalmess="鏈接過期"returnfalse,messendlocalkeys,tmp={}, {}--提出所有的鍵名并按字符順序排序fork,_inpairs(params)doifk~="sign"thenkeys[#keys + 1] = kendendtable.sort(keys)--根據(jù)排序好的鍵名依次讀取值并拼接字符串成key=value&key=valuefor_,kinpairs(keys)doiftype(params[k])=="string"ortype(params[k])=="number"thentmp[#tmp + 1] = k .. "=" .. tostring(params[k])endend--將salt添加到最后壹甥,計算正確的簽名sign值并與傳入的sign簽名對比,localsignChar=table.concat(tmp,"&") ..secretlocalrightSign=ngx.md5(signChar)ifsign~=rightSignthen--返回錯誤信息localmess="sign error: sign,"..sign.."right sign:"..rightSign.." sign_char:"..signChar--localmess="sign error: sign,"..sign.."right sign:"..rightSign.." sign_char:"..table.concat(tmp,"&")returnfalse,messendreturntrueendfunctionAsciiHandler:access(conf)localbinary_remote_addr=ngx.var.binary_remote_addrifnotbinary_remote_addrthenreturnkong.response.error(403,"Cannot identify the client IP address, unix domain sockets are not supported.")end--獲取參數(shù)localparams={}localget_args=ngx.req.get_uri_args();ngx.req.read_body()localpost_args=ngx.req.get_post_args();union(params,get_args)union(params,post_args)--校驗secretlocalsecret=conf.secretlocalcheckResult,mess=signCheck(params,secret,binary_remote_addr,conf.allow,conf.deny)ifnotcheckResultthenreturnkong.response.error(403,mess)--returnkong.response.exit(403, {message=mess})endendreturnAsciiHandler
schema.lua文件示例如下:
localtypedefs=require"kong.db.schema.typedefs"return{name="ascii",fields={{consumer=typedefs.no_consumer},{protocols=typedefs.protocols_http},{config={type="record",fields={{allow={type="array",elements=typedefs.ip_or_cidr, }, },{deny={type="array",elements=typedefs.ip_or_cidr, }, },{secret={type="string",default="secret",required=true, }, },? ? ? ? ? ? },shorthands={--deprecatedforms,toberemovedinKong3.0{blacklist=function(value)return{deny=value}end},{whitelist=function(value)return{allow=value}end},? ? ? ? ? ? },? ? ? ? },? ? ? ? },? ? },entity_checks={{at_least_one_of={"config.allow","config.deny","config.secret"}, },? ? },}
5.4 hadler.lua規(guī)范
5.5 schema.lua規(guī)范
5.6 docker插件位置存放跟配置
5.6.1 去到docker-compose中配置的kong共享目錄./data壶熏, 將插件儲存在當(dāng)前位置
5.6.2 引入插件位置句柠,并關(guān)聯(lián)插件
sudodocker exec-it-uroot kong_kong_1bashvi/etc/kong/kong.conf# 配置信息plugins=bundled,asciilua_package_path=/data/?.lua;;
其中, /data/?.lua是你插件的路徑棒假,;;保持默認(rèn)溯职,意思是引入原先插件的位置
5.6.3 進(jìn)入到kong容器中,發(fā)布配置并重啟
kongpreparekongreload
5.6.4 去到Konga查看效果
5.6.5 配置并使用插件
出現(xiàn)如下效果說明創(chuàng)建成功
輸入正確的簽名請求地址
5.7 php簽名校驗方法實現(xiàn)(Ascii)
<?php/*** ascii碼從小到大排序* @param array $params* @return bool|string*/functionasc_sort($params=array()){if(!empty($params)) {$p=ksort($params);if($p) {$str='';foreach($paramsas$k=>$val) {$str.=$k.'='.$val.'&';? ? ? ? ? ? }$strs=rtrim($str,'&');return$strs;? ? ? ? }? ? }returnfalse;}$data=['apiKey'=>'123456','time'=>time()];$str='secret';$s_data=asc_sort($data);echo$s_data."<br>";$sign=md5($s_data.$str);echo$sign."<br>";echotime();
6帽哑、參考資料
https://github.com/qianyugang/kong-docs-cn
配置詳解
https://www.cnblogs.com/SummerinShire/p/6628021.html
https://docs.konghq.com/1.2.x/getting-started/configuring-a-service/