您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關實用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進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。