分享一个实用Nodejs npm包:koa-csrf

本篇文章给大家分享一个实用nodejs npm包koa-csrf。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。

分享一个实用Nodejs npm包:koa-csrf

koa-csrf是一个用于防止csrf攻击的koa中间件。

当然关于什么是csrf、以及如何预防这里就不赘述了,有兴趣的可以阅读understanding-csrf。egg处理csrf方案。

首先我们看个简单示例:

const router = require('koa-router')();const CSRF = require('koa-csrf');const csrfMD = new CSRF({  invalidSessionSecretMessage: 'Invalid session secret',  invalidTokenMessage: 'Invalid CSRF token',  invalidTokenStatusCode: 403,});router  .get('/',csrfMD,async (ctx, next) => {    ctx.cookies.set('cid','1234', cookieSet);    // 下发csrf token    await ctx.render('index', {      title: 'EJS !',      csrf: ctx.csrf    });  })  .post('/post', csrfMD ,async (ctx, next) => {    console.log(ctx.method);    ctx.session.email = ctx.request.body.email;    ctx.session.name = ctx.request.body.name;    ctx.redirect('/');  })module.exports = router;

登录后复制

简单理解其工作流程:

客户端请求页面:

服务端为用户当前 session 生成 secret 值,并存到 session 里;根据secret生成csrf token,存到ctx._csrf;下发csrf token到客户端

用户写操作,比如发送post 请求时:

服务端获取客户端传递过来的csrf token;服务端从当前 session找到 secret 值;服务器用secret与接收的csrf token进行校验;

koa-csrf

koa-csrf中关于token的创建、校验逻辑都是在这个csrf包里。

const csrf = require('csrf');class CSRF {  constructor(opts = {}) {    // opts配置对象、并且有提供默认配置    // 允许自定义配置对象进行覆盖    this.opts = Object.assign(      {        // 使 koa 抛出的错误信息内容,默认值为:'Invalid CSRF token'。        // 它可以是一个接收 ctx 作为参数的函数,函数最后返回错误信息内容。        invalidTokenMessage: 'Invalid CSRF token',        // 验证失败时的响应状态码,默认值为:403(Forbidden)        // 跟 invalidTokenMessage 参数一样,它也会被传递给 ctx.throw,用于抛出错误和拒绝请求。        invalidTokenStatusCode: 403,        // 排除的请求方法,默认值为:['GET', 'HEAD', 'OPTIONS']。        excludedMethods: ['GET', 'HEAD', 'OPTIONS'],        // 是否禁止通过查询字符串传递 _csrf 校验 token,默认值为 false        // 如果校验 token 出现在 URL 中,则可能会通过 Referer 泄露,应尽量把 Token 放在表单中,把敏感操作由 GET 改为 POST。        disableQuery: false      },      opts    );    // 生成token generation/verification instance    this.tokens = csrf(opts);    // 早期很多这样的中间件写法、对接koa中间件    return this.middleware.bind(this);  }  // koa中间件  middleware(ctx, next) {    // __defineGetter__ API已经不推荐使用    // 在ctx上挂载csrf属性。    // 当读取ctx.csrf会执行该回调    ctx.__defineGetter__('csrf', () => {      // 如果已经存在直接返回、避免多次生成      if (ctx._csrf) {        return ctx._csrf;      }      // csrf依赖于koa session      if (!ctx.session) {        return null;      }      // 生成一个secret存储在ctx.session.secret      if (!ctx.session.secret) {        ctx.session.secret = this.tokens.secretSync();      }      // 根据上述的secret生成csrf toke存到ctx._csrf      // 一般非框架本身属性,都建议_xx表示私有      ctx._csrf = this.tokens.create(ctx.session.secret);      // 返回      return ctx._csrf;    });    // 挂栽ctx.response.csrf属性    ctx.response.__defineGetter__('csrf', () => ctx.csrf);    // 如果是请求方法黑名单直接不处理    if (this.opts.excludedMethods.indexOf(ctx.method) !== -1) {      return next();    }    if (!ctx.session.secret) {      ctx.session.secret = this.tokens.secretSync();    }    // 从ctx.request.body取出客户端传递过来的_csrf token    // 因此依赖于koa-bodyparser类库    const bodyToken =      ctx.request.body && typeof ctx.request.body._csrf === 'string'        ? ctx.request.body._csrf        : false;    // 除了从body获取token    // 支持从ctx.query._csrf即get方法查询字符串    // 支持从请求头获取 'csrf-token'、'xsrf-token'、'x-csrf-token'、'x-xsrf-token'    const token =      bodyToken ||      (!this.opts.disableQuery && ctx.query && ctx.query._csrf) ||      ctx.get('csrf-token') ||      ctx.get('xsrf-token') ||      ctx.get('x-csrf-token') ||      ctx.get('x-xsrf-token');      // 如果获取失败、根据配置对象的信息、抛出异常    if (!token) {      return ctx.throw(        this.opts.invalidTokenStatusCode,        typeof this.opts.invalidTokenMessage === 'function'          ? this.opts.invalidTokenMessage(ctx)          : this.opts.invalidTokenMessage      );    }    // 校验token失败    if (!this.tokens.verify(ctx.session.secret, token)) {      return ctx.throw(        this.opts.invalidTokenStatusCode,        typeof this.opts.invalidTokenMessage === 'function'          ? this.opts.invalidTokenMessage(ctx)          : this.opts.invalidTokenMessage      );    }    // 校验成功    return next();  }}module.exports = CSRF;

登录后复制

下一期我们看下csrf库,这个里面处理更多相关逻辑。

好了,今天就到这结束了,下期见。

ps:如果你对node也有兴趣,欢迎关注我公众号:xyz编程日记。

相关推荐:《nodejs 教程》

以上就是分享一个实用Nodejs npm包:koa-csrf的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2714138.html

(0)
上一篇 2025年3月7日 21:31:17
下一篇 2025年3月6日 20:26:08

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • Windows环境下Nodejs多版本间如何切换?

    本篇文章给大家介绍一下windows环境下node多版本间进行切换的方法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。 NodeJS多版本切换使用(Windows) 优先安装nvm版本管理工具通过安装包安装nodejs:…

    2025年3月7日
    200
  • 详解Nodejs+Nest实现的短链接服务

    本篇文章给大家介绍一下基于node框架nest实现短链接服务的方法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。 推荐学习:《node》 日常生活中能见到各种奇怪的短链接,每次点击跳转的时候,笔者都会觉得神奇,这短链是怎…

    2025年3月7日
    200
  • 聊聊Nodejs获取参数的四种方法

    本篇文章给大家介绍一下nodejs获取参数的四种方法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。 推荐学习:《nodejs》 获取请求很中的参数是每个web后台处理的必经之路,nodejs的 express框架 提供了…

    2025年3月7日
    200
  • 深入浅析Node.js中的进程和线程

    本篇文章带大家深入了解一下node.js中的进程和线程。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。 进程与线程是一个程序员的必知概念,面试经常被问及,但是一些文章内容只是讲讲理论知识,可能一些小伙伴并没有真的理解,在实…

    2025年3月7日 编程技术
    200
  • 详解nodejs在控制台打印高亮代码的方法

    本篇文章给大家介绍一下nodejs如何在控制台打印高亮代码。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。 当代码运行报错时,我们会打印错误,错误中有堆栈信息,可以定位到对应的代码位置。但有的时候我们希望能够更直接准确的打…

    2025年3月7日 编程技术
    200
  • 详解Nodejs Buffer模块的常用API

    本篇文章带大家详细介绍一下nodejs buffer模块的常用api。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。 模块概览 Buffer是node的核心模块,开发者可以利用它来处理二进制数据,比如文件流的读写、网络请求…

    2025年3月7日
    200
  • Nodejs中使用string_decoder模块将buffer转成string

    本篇文章给大家介绍一下nodejs中使用string_decoder模块将buffer转成string的方法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。 模块简介 string_decoder模块用于将Buffer转成…

    2025年3月7日
    200
  • nodejs设置NODE_ENV时发生错误怎么解决?

    本篇文章给大家介绍一下windows环境中nodejs设置node_env错误的解决方案。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。 【推荐学习:《nodejs》】 今天在看node文档的时候,看到《Node.js 开…

    2025年3月7日 编程技术
    200
  • 详解Nodejs中的阻塞和非阻塞

    本篇文章带大家理解一下nodejs中的阻塞和非阻塞。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。 推荐学习:《nodejs》 对于阻塞和非阻塞这两个概念大家应该都有一些自己的理解: 再简单说一下,阻塞大部分是由于同步模式…

    2025年3月7日
    200
  • 如何使用Nodejs连接Mysql,实现基本的增删改查操作

    本篇文章给大家介绍一下如何使用nodejs连接mysql,实现基本的增删改查(crud)操作。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。 【推荐学习:《nodejs》】 接下来示例代码的主要技术点包括 基础框架 Koa…

    2025年3月7日 编程技术
    200

发表回复

登录后才能评论