因为最近要开发自定义kong认证插件,比如使用casbin鉴权或者cas sso 单点登录等功能。遇到避免二次登录的问题,故考虑使用Kong 自带的session插件。
那么就遇到了第一个问题,session插件是怎么工作的?
一,获取源码
kong session 源码地址 https://github.com/Kong/kong-plugin-session
在plugins目录我们看到一个标准的kong插件文件列表
二,handler.lua
handler.lua定义了优先级为1900,并将hearder_filter,和access两个方法委托给了hearder_filter,access两个文件。
三,一个重要的问题
handler的优先级为1900,高于所有内置认证的插件。那么按照从高到底执行的逻辑,session插件应该优先于所有认证插件的执行。
既然session插件是第一个执行的,并不知道后续认证插件是否认证成功,那么session插件怎么可能又知道认证成功后去设置session呢?
经研究,我发现插件认证顺序并不完全像文档上说的,按照优先级次序执行的。
具体来说,插件阶段分为两个部分,即将请求实际转发前和转发后。
从上到下,access及之前是转发前的动作,hearder_filter及之后是转发后请求返回后的动作。在不同插件间,转发前的动作是按PRIORITY优先级从大到小的顺序执行,而转发后的动作按优先级从小到大执行。
这样就很好明白,session插件首先是在access中判断是否有cookie,验证权限。然后执行权限插件验证。如果验证成功最后执行session插件中header_filter逻辑,写session。用于下次请求。
四,验证源码
access.lua
header_filter.lua
看下源码,果然是这样。
五,那么自定义插件怎么使用session插件呢
在header_filter.lua中,_M.execute(conf)方法前两行:
local credential = kong.client.get_credential()
local consumer = kong.client.get_consumer()
加上之后的逻辑我们可以看到,其实session判断的是以上两个变量。
所以我们自定义认证插件中,PRIORITY 小于1900,然后在认证结束后设置kong.client.get_credential(),kong.client.get_consumer()两个变量就好了。
具体设置方法可以使用kong.client.authenticate(consumer, credential)
方法。
以上