1. 程式人生 > 程式設計 >koa2的中介軟體功能及應用示例

koa2的中介軟體功能及應用示例

最近因為開發一個自己的部落格網站,學習了koa2的搭建,寫了一些自己認為比較重要或需要知道的koa2中介軟體作用和使用場景。

koa-router

路由中介軟體

下載

npm i koa-router 

使用

普通使用方法

需要注意的是引入的koa-router是一個方法,引入後需要執行這個方法。

const Koa = require('koa'); 
const app = new Koa(); 
const router = require('koa-router')(); 

// 配置路由url 
// 預設url 
router.get('/',async (ctx,next) => { 
 ctx.body = 'Hello World'; 
}); 

// 自定義url 
router.get('/hello/:name',next) => { 
 var name = ctx.params.name; 
 ctx.response.body = \`<h1>Hello,${name}!</h1>\`; 
}); 

// 註冊路由 
app.use(router.routes(),router.allowedMethods()); 

也可以按需引入並註冊路由,可註冊多個路由。

不同請求下接收的引數獲取

router.get

通過ctx.query獲取引數

router.post
通過ctx.request.body獲取引數

動態路由 router.get('/:id',func)
通過ctx.params獲取引數

遍歷註冊router

首先引入nodejs中的fs模組,使用fs的readdirSync方法獲取到指定目錄的所有檔名,遍歷引入路由模組並註冊。

const fs = require('fs');

// fs.readdirSync 獲取指定目錄下的所有檔名稱,遍歷引入路由模組並註冊 
fs.readdirSync('./routes').forEach(route=> { 
 let api = require(\`./routes/${route}\`); 
 app.use(api.routes(),api.allowedMethods()); 
}); 

koa-router中的其它api

router.prefix(prefix) 新增url字首

設定已經初始化的路由器例項的路徑字首

router.prefix('/user'); 
router.post('/login',function(ctx,next) { 
 ... 
}); 

// 實際路徑 /user/login 

router.use(url|[url1,url2,...],(ctx,next) => {...}) 路由中介軟體

使用場景:我們通常需要通過驗證使用者和使用者許可權來判定使用者是否能使用該介面,如果在每個介面都寫一次驗證非常麻煩且不好維護。這時我們就需要路由中介軟體先進行驗證,再執行下面操作。

router.use的第一個引數為一個路徑或者由多個需要使用中介軟體的路徑組成的陣列(需要注意的是,如果路由設定了url字首,需要在設定字首後註冊中介軟體,引數中的url不需要設定字首)。

router.use的第二個引數為函式,函式傳遞ctx和next兩個引數,可通過ctx進行許可權驗證後,判斷是否執行next呼叫介面。這裡特別需要注意的是函式使用next的時候需要新增await,如果不新增,在呼叫介面前,介面就會返回結果,前臺則無法獲取到資料。

 // this is wrong 
 app.use(function (ctx,next) { 
  ctx.set("Access-Control-Allow-Origin","\*"); 
  next(); 
 }); 
 // this is right 
 app.use(async function (ctx,"\*"); 
  await next(); 
 }); 

koa-bodyparser處理post請求

處理post請求時,我們會遇到一個問題,無論是node的request物件還是koa的request物件,都沒辦法解析request的body,我們就需要下載並引入一個解析body的中介軟體koa-bodyparser,koa-bodyparser的具體配置詳見下面的說明,這裡我們直接放入使用方式。

 // 引入路由檔案 
 const index = require('./routes/index.js'); 
 const user = require('./routes/user.js'); 

 // 引入解析request.body的中介軟體 
 const bodyparser = require('koa-bodyparser'); 

 // 註冊bodyparser,需要注意,bodyparser的註冊一定要在router路由註冊之前 
 app.use(bodyparser({ 
  enableTypes:\['json','form','text'\] 
 })); 

 ... 

 // 註冊routes 
 app.use(index.routes(),index.allowedMethods()); 
 app.use(user.routes(),user.allowedMethods()); 

koa-bodyparser

如上所述,koa-bodyparser用於解析request.body,因為node和koa的request無法解析body。

下載

 npm i koa-bodyparser 

使用

const bodyparser = require('koa-bodyparser');

在註冊執行時,bodyparser方法中可傳入物件,作相應配置。

- enableTypes:解析器只在配置了enableTypes時解析請求型別,預設是['json', 'form']。
- encoding:請求編碼,預設是utf-8。
- formLimit:urlencoded body的imit如果主體最終大於此限制,則返回一個413錯誤程式碼。預設是56 kb。
- jsonLimit:json主體的限制。預設是1 mb。
- textLimit:文字主體的限制。預設是1 mb。
- strict:當設定為true時,JSON解析器將只接受陣列和物件。預設是正確的。參見正文中的嚴格模式。在嚴格模式下,ctx.request。body總是一個物件(或陣列),這避免了很多型別判斷。但文字正文總是返回字串型別。
- detectJSON:自定義json請求檢測函式。預設為null。

app.use(bodyparser({ 
 detectJSON: function (ctx) { 
 return /\\.json$/i.test(ctx.path); 
 } 
})); 

- extendTypes:支援擴充套件型別

  app.use(bodyparser({ 
   extendTypes: { 
   json: \['application/x-javascript'\] // 解析application/x-javascript 型別 作為JSON字串 
   } 
  })); 

- onerror:支援自定義錯誤控制代碼,如果koa-bodyparser丟擲一個錯誤,您可以自定義響應如下:

  app.use(bodyparser({ 
   onerror: function (err,ctx) { 
   ctx.throw('body parse error',422); 
   } 
  })); 

- disableBodyParser:可以通過設定ctx動態禁用body解析器。disableBodyParser = true。

  app.use(async (ctx,next) => { 
   if (ctx.path === '/disable')     ctx.disableBodyParser = true; 
   await next(); 
  }); 
  app.use(bodyparser()); 

koa-logger

請求響應監聽日誌

下載

npm i koa-logger 

使用

~~// 引入日誌中介軟體 
const logger = require('koa-logger'); 

// 註冊日誌中介軟體 
app.use(logger()); ~~

koa-session

用於Koa的簡單會話中介軟體。預設為基於cookie的會話,並支援外部儲存。

session

我們知道,http協議是無狀態的,當用戶進行登入後,並不會儲存賬戶密碼,如果我們需要維持使用者的登入狀態,就需要使用一些方法。目前主流的使用者認證方法有基於token和基於session兩種方式。

基於token的認證可以使用koa-jwt中介軟體,基於session的認證則使用標題的koa-session。

下載

npm i koa-session

使用

app.js 入口檔案中註冊session

const CONFIG = { 
 key: 'koa:sess',/\*\* (string) cookie key (default is koa:sess) \*/ 
 /\*\* (number || 'session') maxAge in ms (default is 1 days) \*/ 
  // 狀態儲存最大時間,預設為一天 
 maxAge: 86400000,autoCommit: true,/\*\* (boolean) 自動儲存頭部 (default true) \*/ 
 overwrite: true,/\*\* (boolean) 能否覆蓋 (default true) \*/ 
 httpOnly: true,/\*\* (boolean) httpOnly or not (default true) \*/ 
 signed: true,/\*\* (boolean) signed or not (default true) \*/ 
 /\*\* (boolean) 強制在每個響應上設定會話識別符號cookie。過期將重置為原始maxAge,重新設定過期倒計時。 (default is false) \*/ 
 rolling: false,/\*\* (boolean) 當會話快過期時續訂會話,這樣我們可以始終保持使用者登入。(default is false)\*/ 
 renew: false,}; 

// 如果你所有都為預設配置,則不需要傳遞配置引數,app.use(session(app))即可 
app.use(session(sessionConfig,app)); 

session的使用

註冊後可以通過上下文ctx找到session屬性,下面程式碼將使用者資訊存入session屬性中,並建立key和value

user.js

// 使用者登入 
static async login(ctx,next) {

const data = ctx.request.body 
const schema = Joi.object().keys({ 
 username: Joi.string().required(),password: Joi.string().required(),}) 
let result = Joi.validate(data,schema) 
// 如果有欄位型別錯誤 
if(result.error) { 
 return ctx.response.body = { status: 400,msg: result.error.details}; 
} 
let { username,password } = result.value // 驗證過後的資料 
// 查詢是否有該使用者 
const userInfo = await usersModel.findByName(username) 
// 如果有該使用者,繼續驗證密碼是否正確 
if (userInfo) { 
 const userInfo2 = await usersModel.findOne({ username,password }) 
 if (userInfo2) { 
  ctx.response.body = {state: 200,msg: '登入成功'} 
  // 設定session 
  ctx.session.userInfo = userInfo2 
 } else { 
  ctx.response.body = {state: 410,msg: '密碼錯誤'} 
 } 
// 如果沒有該使用者,返回結果 
} else { 
 ctx.response.body = {state: 410,msg: '該使用者不存在'} 
} 
return ctx.response.body 
}

koa-router路由中介軟體中驗證session,這裡需要注意的是next()方法前一定要使用await,不然程式不會等待next()方法執行。

export const verifyUser = async (ctx,next) => {

if (ctx.session.userInfo) { 
 await next() 
} else { 
 return ctx.response.body = { state: 401,msg: '無許可權訪問' } 
} 
}

koa2-cors

用於解決跨域問題

下載

npm install koa2-cors

使用

app.use(cors())

到此這篇關於koa2的中介軟體功能及應用示例的文章就介紹到這了,更多相關koa2 中介軟體內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!