中间件

未匹配的标注

中间件是请求尚未到达路由处理程序之前的一系列函数。
函数链中的每一个中间件函数都有能力结束请求或通过 next 转发这个请求到下一个中间件函数。

基础例子

添加一个中间件最简单的方式是使用Route.middleware 方法直接附加在路由上。例如:

Route
  .get('/users/:id', async () => {
    return 'Show user'
  })
  // highlight-start
  .middleware(async (ctx, next) => {
    console.log(`Inside middleware ${ctx.request.url()}`)
    await next()
  })
  // highlight-end

查看视频演示

中间件类

在某些需要快速测试的情况下,内联函数是一个不错的方式。但是,我们建议将中间件提取到单独的文件中。您可以通过运行以下Ace命令,创建一个新的中间件。

node ace make:middleware LogRequest

# CREATE: app/Middleware/LogRequest.ts

关于中间件类

中间件类文件存储在app/Middleware文件夹下(不是必须的),每个文件都代表一个单独的中间件。

中间件必须实现 handle方法用于处理请求,并且调用next 方法转发请求到下一个中间件,或路由处理程序。

// title: app/Middleware/LogRequest.ts
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'

export default class LogRequest {
  public async handle(
    { request }: HttpContextContract,
    next: () => Promise<void>
  ) {
    console.log(`-> ${request.method()}: ${request.url()}`)
    await next()
  }
}

你也可以在中间件中,抛出异常终止请求。 或者使用response.send方法响应请求。

注:当你想结束请求时候,不要调用next 方法。

import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'

export default class Auth {
  public async handle(
    { request, response }: HttpContextContract,
    next: () => Promise<void>
  ) {
    if (notAuthenticated) {
      response.unauthorized({ error: 'Must be logged in' })
      return
    }

    await next()
  }
}

注册中间件

为了让中间件生效,你必须在start/kernel.ts文件中,将它注册为 全局中间件 或者一个 命名中间件

全局中间件

全局中间件,是一个中间件队列。中间件会按照他们注册的顺序,一个个的处理HTTP请求。
你在start/kernel.ts文件中注册中间件时,就想下面一样注册:

// title: start/kernel.ts
Server.middleware.register([
  () => import('@ioc:Adonis/Core/BodyParser'),
  // highlight-start
  () => import('App/Middleware/LogRequest')
  // highlight-end
])

命名中间件

命名中间件允许你选择性的在路由组单个路由中,使用你的中间件。
首先用唯一的名称注册它们,然后在路由上引用它。

// title: start/kernel.ts
Server.middleware.registerNamed({
  auth: () => import('App/Middleware/Auth')
})

现在,你可以将auth 中间件,挂载到路由中。如下:

Route
  .get('dashboard', 'DashboardController.index')
  .middleware('auth') // 👈

中间件可以用于资源路由的一个或多个操作。学习更多 applying middleware to resourceful routes.

您还可以将它们作为数组多次调用中间件,用这种方式挂载多个中间件。

Route
  .get('dashboard', 'DashboardController.index')
  .middleware(['auth', 'acl', 'throttle'])
Route
  .get('dashboard', 'DashboardController.index')
  .middleware('auth')
  .middleware('acl')
  .middleware('throttle')

将配置传递给指定中间件

命名中间件也可以通过handle方法的第三个参数,在运行时接受配置参数,例如:

export default class Auth {
  public async handle(
    { request, response }: HttpContextContract,
    next: () => Promise<void>,
    // highlight-start
    guards?: string[]
    // highlight-end
  ) {
    await next()
  }
}

上例中,Auth 中间件接收一个可选的 guards 数组。中间件用户可以这样传入 guards:

Route
  .get('dashboard', 'DashboardController.index')
  .middleware('auth:web,api')

FAQs

怎样让给定的 HTTP 请求禁用中间件?

你不能让指定的 HTTP 请求禁用中间件。不过,中间件可以通过接收一个运行时配置,来忽略特定请求。

以 bodyparser 中间件为例。它[忽视不能匹配白名单方法的所有请求](https://github.com/adonisjs/bodyparser/blob/develop/src/BodyParser/index.ts#L108-L111),这些白名单方法在 `config/bodyparser.ts` 文件中定义。

中间件是否在没有路由的请求中执行?

如果当前的 HTTP 请求没有注册路由,AdonisJS 不会执行中间件。

本文章首发在 LearnKu.com 网站上。

本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

原文地址:https://learnku.com/docs/adonisjs/5.x/ht...

译文地址:https://learnku.com/docs/adonisjs/5.x/ht...

上一篇 下一篇
贡献者:3
讨论数量: 0
发起讨论 只看当前版本


暂无话题~