抵御 CSRF 攻击
jianchao
2024-09-30 09:32
· edited
概览#
跨站请求伪造(Cross-Site Request Forgery, CSRF)是一种攻击方式。攻击者通过诱导受害者访问一个恶意网站,在受害者不知情的情况下,向受信任网站发送伪造的请求。这些请求会沿用用户当前认证会话的凭证,从而能够利用用户的身份和权限进行破坏性操作,例如更改账户信息、删除数据等。
先决条件#
- 具备一定编程基础的开发者
接入#
为了防御 csrf
攻击,我们分别在前端和后端提供了接口防御:
- @blocklet/sdk:为后端提供了
csrf
中间件,用于验证csrf token
。只有在成功通过验证后,系统才会正常处理相关请求。 - @blocklet/js-sdk:为前端提供了
createAxios
,createFetch
函数,在发送请求的时候携带csrf token
。
后端#
@blocklet/sdk 为后端提供了 express
的 csrf
中间件,用于验证 csrf token
。
基础用法#
默认情况下,@blocklet/sdk 导出的 csrf
中间件会拦截所有含有副作用的接口(比如 POST,PUT 请求),并验证它们的 csrf token
是否有效。
如果验证失败,则会抛出错误: Current request status is abnormal, please retry later
。
import { csrf } from '@blocklet/sdk/lib/middlewares';
app.use(csrf());
进阶用法#
在某些情况下,我们也许需要根据业务逻辑,放行某些请求,此时我们可以通过自定义 csrf token 的 verifyToken 函数实现。
import { csrf } from '@blocklet/sdk/lib/middlewares';
app.use(
csrf({
verifyToken: async (req, res) => {
const needVerifyToken = ...;
if (needVerifyToken) { // only need to verify in certain cases
await res.locals.verifyToken(req, res);
}
},
})
);
前端#
@blocklet/js-sdk 为前端提供了 createAxios
,createFetch
函数,在发送请求的时候携带 csrf token
。
基础用法#
@blocklet/js-sdk 导出的 createAxios
函数,会在前端发送(含有副作用的)请求之前携带 csrf token
到请求头中。用户后端的 csrf token
中间件会对 token 进行校验,校验成功后,请求才会被处理。
import { createAxios } from '@blocklet/js-sdk';
const api = createAxios({}); // It can also be createFetch
// when making a request, the csrf token will be automatically included in request.headers['x-csrf-token']
await api.put(...);
接入成功之后,你将可以在请求头中看到 csrf-token,就像下面这样:
使用其他的前端请求库#
import { getCSRFToken } from '@blocklet/js-sdk';
// Send the request with the CSRF token in the header.
request.headers['x-csrf-token'] = getCSRFToken();
Sticker