koa2实现网站csrf防御
什么是csrf攻击?
csrf/xsrf又叫跨站请求伪造。
先说常见的登陆鉴权: 用户在你的网站登陆后,一般把登陆凭证(token)存储在cookie里,之后每次调接口都会自动携带,后端根据这条cookie鉴权,判定是登陆状态,进而允许进行安全操作。
虽然这种鉴权方式最为简便,但存在一种安全隐患,就是csrf。
csrf攻击者会利用http请求自动携带cookie的机制,在用户登陆后,引导用户点击它的攻击链接,进而拿到用户的token去进行恶意请求,比如购买商品,虚拟货币转账......造成的问题包括:个人隐私泄露以及财产安全。
防御csrf攻击
思路:
由于csrf攻击者只能拿到cookie去干坏事,但它无法知道cookie里有什么,也拿不到其他有效信息。我们只需要除cookie外再加一道它做不到的验证就可以了。
前端首次加载页面的时候,调接口让后端植入一条csrfToken到cookie里。然后前端每次请求从cookie里取出然后放到请求头里给后端传输。
后端将植入给前端的csrfToken存储在session,然后一些安全接口(一般是除了get请求外的接口),请求时,需要先进行csrf比对,取出request请求头里的csrfToken和自己session里的csrfToken进行比对,完全一致才放行
代码实现
前端(react)
1//App.tsx
2//根组件,判断cookie里有没有csrfToken,没有就请求后端种植
3 useEffect(() => {
4 if (!cookie.get("csrf_token")) {
5 request("/all/getCsrfToken");
6 }
7 }, []);
1//request.ts
2//axios请求拦截器内置了csrf方法,如下配置即可自动取出cookie里的csrf并放到请求头
3request.interceptors.request.use((config: any) => {
4 // 开启顶部加载进度条
5 Nprogress.start();
6
7 config.xsrfHeaderName = "X-CSRF-TOKEN";
8 config.xsrfCookieName = "csrf_token";
9
10 return config;
11});
后端(koa2)
后端利用koa-csrf中间件实现
1yarn add koa-csrf
1、先封装一个csrf实例
1//先封装一个csrf实例
2const CSRF = require("koa-csrf");
3
4const csrfMD = new CSRF({
5 invalidSessionSecretMessage: "Invalid session secret",
6
7 invalidTokenMessage: "Invalid CSRF token",
8
9 invalidTokenStatusCode: 403,
10});
11
12module.exports = csrfMD;
参数:
invalidTokenMessage
使 koa 抛出的错误信息内容,默认值为:"Invalid CSRF token"。它可以是一个接收 ctx 作为参数的函数,函数最后返回错误信息内容。
invalidTokenStatusCode
验证失败时的响应状态码,默认值为:403(Forbidden)。跟 invalidTokenMessage 参数一样,它也会被传递给 ctx.throw,用于抛出错误和拒绝请求。
excludedMethods
排除的请求方法,默认值为:["GET", "HEAD", "OPTIONS"]。
disableQuery
是否禁止通过查询字符串传递 _csrf 校验 token,默认值为 false。如果校验 token 出现在 URL 中,则可能会通过 Referer 泄露,应尽量把 Token 放在表单中,把敏感操作由 GET 改为 POST。
2、写一个给前端种植csrfToken的接口(必须是get)
1const Csrf = require("@utils/csrf");
2
3router.get("/getCsrfToken", Csrf, async (ctx) => {
4 ctx.cookies.set("csrf_token", ctx.csrf, {
5 httpOnly: false,
6 maxAge: 24 * 60 * 60 * 1000,
7 });
8
9 ctx.body = "csrfToken种植成功!";
10});
3、需要防御csrf的接口(post|put|delete),使用csrf即可自动校验
1router.delete("/delete",Csrf, async (ctx) => {
2 const { id } = ctx.query;
3 const result = await sql(`delete from user where id="${id}"`);
4
5 ctx.body = result;
6});
相关文章
- Cloud Studio搭建网站新姿势
- electron套壳web网站应用实现标签页
- 这10 个很“哇塞”的Web资源,前端必备的神仙级网站
- 数据库学习网站
- 国内外常用的MD5在线解密网站
- PHP网站默认端口/查询本地端口/PHP是编译型语言
- 一个网站部署的详细流程!步骤齐全!少走坑路
- 网站最近动态
- 用2核2G的入门级云服务器搭建个人博客网站
- 客服系统切换中英文多语言 - 使用js更新URL参数来实现切换 【唯一客服】网站网页客服源码教程
- 客服系统即时通讯IM开发(三)访客实现一对一聊天-访客生成唯一id标识存储到全局变量【唯一客服】网站在线客服系统
- 推荐几个好用的AI生成工具和办公效率网站
- 营销型网站建设有哪些技巧?建营销型网站需要注意什么
- Embedly:一个 API 就能嵌入 100 多个网站的资源
- 如何提高服务器、网站安全性
- Linux下架设网站的步骤详解(linux如何搭建网站)
- 利用Redis实现网站流量统计(redis流量统计)
- Linux搭建网站:一步步轻松实现(linux创建网站)
- 社交网站推特正在测试不喜欢按钮 既然能点喜欢那为什么不能点不喜欢呢?
- MySQL学习之旅:从网站开始(mysql学习网站)
- 提升MSSQL网站安全保障,实现健康稳定运行(提高mssql网站安全性)
- PHP与MySQL实现网站优化,让分页更高效(phpmysql分页)
- Redis缓存实现网站导航条的优化(导航条用redis做缓存)
- Redis在网站中的卓越应用实现更好的性能(redis适合做什么功能)
- 网站用php实现paypal整合方法
- python登陆asp网站页面的实现代码
- 使用ob系列函数实现PHP网站页面静态化