目录
Kong 项目构成
这个项目只是做了鉴权,属于内网网关,流量在这之前还会经过一道外网网关,那边有流控,请求分发,配置证书等功能,内网网关只是做鉴权,流量打到这边鉴权之后不同的路由转发到 k8s 的不同 service 里调用具体的服务。
项目部署了线上网关和测试环境网关两种环境,提供的plugins插件鉴权有 APP端的鉴权,C端和B端鉴权,这里我主要讲的是B端的鉴权,其他的简单介绍一下:
B端鉴权lua脚本
local ngx_re = require "ngx.re"
local BasePlugin = require "kong.plugins.base_plugin"
local string = require "resty.string"
local BuserResolveHandler = BasePlugin:extend()
function BuserResolveHandler:new()
BuserResolveHandler.super.new(self, "buser-resolve")
end
function BuserResolveHandler:access(conf)
BuserResolveHandler.super.access(self)
local cookieName = "cookie_" .. "KUAIZHAN_V2"
local kuaizhanV2 = ngx.var[cookieName]
-- ngx.log(ngx.ERR, "kuaizhanV2", kuaizhanV2)
local uid = 0
ngx.req.set_header("X-User-Id", uid)
// cookie 内容 3001459%7C1636684996%7C7180720502%7Cb61a12ef865072964aa359e6a9ef2e0b1846dee9
if xxx_V2 and xxx_V2 ~= '' then
local res, err = ngx_re.split(xxxV2, "%7C")
if err then
return
end
// 解析得到 userId, time, nonce, sign,
// 分别为 3001459,1636684996,7180720502,b61a12ef865072964aa359e6a9ef2e0b1846dee9
local userId, time, nonce, sign = res[1], res[2], res[3], res[4]
// 根据密钥,时间,签名,利用 hmac_sha1 算法,十六进制算法,得到摘要签名
local digest = ngx.hmac_sha1(conf.secret, userId .. time .. nonce)
local theSign = string.to_hex(digest)
-- TODO 加上过期时间判断
// 计算签名和cookie解析得到sign 是否相同,相同则赋值uid
if theSign == sign then
uid = userId
end
ngx.log(ngx.ERR, "theSign:", theSign, "sign:", sign, "uid:", uid)
end
ngx.log(ngx.ERR, "get x-user-id:" .. uid)
// nginx 请求头header里面存放 X-User-Id,再转发到各个业务线
ngx.req.set_header("X-User-Id", uid)
end
return BuserResolveHandler
但是多端,或者跨顶域情况下的单点登录是没法做的。
不知道大家有没有关注到第一张 cookie 截图后面有个失效时间,这种由于依赖 cookie,因此只要到期就会被踢下线,需要重新登录,一定程度上影响客户体验。
现在的很多应用都利用 token + redis 方案实现了登录续期,例如连续十天内有过登录,那么不需要再次登录,后端实现自动续期,十天以上都没有登录过的才失效需要重新登录。
但是续期服务需要 redis 成本,这种省成本。
这种方案的注销,只是简单的删除 cookie,如果有心人拿到 cookie 仍然是可以用的,这个 cookie 在有效期内不会失效。
token+redis 方案可以做到真实的 token 失效。