这篇文章将为大家详细讲解有关实用Nodejs npm包:koa-csrf的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。
JS是JavaScript的简称,它是一种直译式的脚本语言,其解释器被称为JavaScript引擎,是浏览器的一部分,主要用于web的开发,可以给网站添加各种各样的动态效果,让网页更加美观。
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中关于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;
关于“实用Nodejs npm包:koa-csrf的示例分析”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。