apisix~csrf插件
配置信息
{
key: token的密鑰
expires:過期時間,默認7200(秒)
name: token在cookie中的名稱,默認是apisix-csrf-token
}
插件解釋
先在cookie中寫(xie)入csrf-token
local function gen_sign(random, expires, key)
local sha256 = resty_sha256:new()
local sign = "{expires:" .. expires .. ",random:" .. random .. ",key:" .. key .. "}"
sha256:update(sign)
local digest = sha256:final()
return str.to_hex(digest)
end
local function gen_csrf_token(conf)
local random = math.random()
local timestamp = ngx_time()
local sign = gen_sign(random, timestamp, conf.key)
local token = {
random = random,
expires = timestamp,
sign = sign,
}
local cookie = ngx_encode_base64(core.json.encode(token))
return cookie
end
function _M.header_filter(conf, ctx)
local csrf_token = gen_csrf_token(conf)
local cookie = conf.name .. "=" .. csrf_token .. ";path=/;SameSite=Lax;Expires="
.. ngx_cookie_time(ngx_time() + conf.expires)
core.response.add_header("Set-Cookie", cookie)
end
一個(ge)csrf-token由(you)隨機數,過期時(shi)間(jian),簽名(ming)組成,下面介紹一下這3個(ge)參數
- random 隨機數
- expires 過期時間
- sign = 上面兩個參數+key的sha256的散列數
- 最后把這三個數進行base64寫到cookie里
post,put,delete這些會改變數據(ju)狀態(tai)的請求,需要進行csrf的防護,在postman里可以這樣測(ce)試
- scripts里添加腳本
var xsrfCookie = postman.getResponseCookie("apisix-csrf-token");
if (xsrfCookie) {
pm.environment.set("xsrf-token", decodeURIComponent(xsrfCookie.value)); // 第一次請求后,正確的token就寫到postman的cookie里了,下次post請求帶上就對了
}
- header中添加csrf
- cookie里的csrf也會被傳到apisix
- 最后將header和cookie里的值進行比較
如果(guo)出現apisix-csrf-token被(bei)篡改,會返(fan)回401
{"error_msg":"csrf token mismatch"}