【问题标题】:how to implement before filter in koa framwork?如何在koa框架中实现前置过滤器?
【发布时间】:2016-06-21 02:23:29
【问题描述】:

我正在使用 koa 来实现一个应用程序,我想实现一个前置过滤器,就像 ruby on rails 中的 before_action 一样:

class UsersController < ApplicationController
  before_action :logged_in_user, only: [:edit, :update]

    # Before filters

    # Confirms a logged-in user.
    def logged_in_user
      unless logged_in?
        flash[:danger] = "Please log in."
        redirect_to login_url
      end
    end
end

需要指出的一点是,我不想过滤所有 api,只过滤其中一些,例如 update_user delete_user

【问题讨论】:

    标签: node.js filter koa


    【解决方案1】:

    你会使用中间件。

    const app = require('koa')();
    const router = require('koa-router')();
    
    function * ensureLoggedIn (next) {
      if (!this.currentUser) {
        this.redirect('/login')
        return 
      }
      // If we get this far, then we know the user is logged in and 
      // we can yield to the downstream routes.
      yield * next
    }
    
    router.get('/users', function * () {...})
    router.get('/users/:id/edit', ensureLoggedIn, function * () {...})
    router.post('/user/:id', ensureLoggedIn, function * () {...})
    
    app.use(router.routes()).listen(3000)
    

    这是最通用的方式。根据您使用的路由库,您可能还有其他选择。

    例如,koa-router 允许您实现特定于路由器的中间件,该中间件仅在请求与路由器匹配时运行。

    const unrestricted = require('koa-router')();
    unrestricted.get('/users', function * () {...})
    
    const loggedIn = require('koa-router')();
    loggedIn.use(ensureLoggedIn)
    loggedIn.get('/users/:id/edit', function * () {...})
    loggedIn.post('/user/:id', function * () {...})
    
    app.use(unrestricted.routes()).use(loggedIn.routes()).listen(3000)
    

    或者您可以使用router.param(name, middleware) 指定仅在具有该 URL 参数的路由上运行的中间件:

    const router = require('koa-router')();
    
    // Only run the given middleware if the URL has the "id" parameter
    router.param('id', ensureLoggedIn, loadUser)
    
    router.get('/users', function * () {...})
    router.get('/users/:id/edit', function * () {...})  // <-- 
    router.post('/user/:id', function * () {...})       // <--
    
    app.use(router.routes()).listen(3000)
    

    【讨论】:

    • 如果我必须在我的路由中使用该通用函数的输出,或者将其传递给我的视图 - 我想知道该怎么做。
    • @Qasim 您可以在中间件中设置上下文对象的信息(koa1 中的this,或 koa2 中处理程序/中间件的第一个参数)。例如,ctx.currentUser = { uname: 'foo' }。为此,Koa 在ctx.state = {} 有一个空对象,这是设置此类数据的合适位置,因为它不会与任何其他属性发生冲突。 ctx.state.currentUser = { uname: 'foo' }。请注意,我的答案是针对 koa1 (2016)。
    猜你喜欢
    • 1970-01-01
    • 2016-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-30
    • 2017-04-26
    • 1970-01-01
    • 2015-12-29
    相关资源
    最近更新 更多