我正在尝试创建一个接受配置的自定义Buffalo(gobuffalo)中间件。问题是我无法通过以下错误跳过中间件功能:

actions / app.go:63:22:无法在app.Middleware.Skip的参数中使用myMiddlewareFunc(类型func(myConfig)buffalo.MiddlewareFunc)作为buffalo.MiddlewareFunc类型

到目前为止,我得到的代码是:

package actions

import (
    "github.com/gobuffalo/buffalo"
    "github.com/gobuffalo/buffalo/middleware"
    "github.com/gobuffalo/envy"

    "github.com/gobuffalo/buffalo/middleware/csrf"
    "github.com/gobuffalo/buffalo/middleware/i18n"
    "github.com/gobuffalo/packr"
)

// ENV is used to help switch settings based on where the
// application is being run. Default is "development".
var ENV = envy.Get("GO_ENV", "development")
var app *buffalo.App
var T *i18n.Translator

type myConfig struct {
    value string
}

// App is where all routes and middleware for buffalo
// should be defined. This is the nerve center of your
// application.
func App() *buffalo.App {
    if app == nil {
        app = buffalo.New(buffalo.Options{
            Env:         ENV,
            SessionName: "_myapp_session",
        })
        // Automatically redirect to SSL
        app.Use(ssl.ForceSSL(secure.Options{
            SSLRedirect:     ENV == "production",
            SSLProxyHeaders: map[string]string{"X-Forwarded-Proto": "https"},
        }))

        if ENV == "development" {
            app.Use(middleware.ParameterLogger)
        }

        // Protect against CSRF attacks. https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)
        // Remove to disable this.
        app.Use(csrf.New)

        // Wraps each request in a transaction.
        //  c.Value("tx").(*pop.PopTransaction)
        // Remove to disable this.
        app.Use(middleware.PopTransaction(models.DB))

        // Setup and use translations:
        var err error
        if T, err = i18n.New(packr.NewBox("../locales"), "en-US"); err != nil {
            app.Stop(err)
        }
        app.Use(T.Middleware())
        app.Use(myMiddlewareFunc(myConfig{
            value: "test value",
        }))
        app.Middleware.Skip(myMiddlewareFunc, TestHandler)
        app.GET("/", HomeHandler)
        app.GET("/test", TestHandler)

        app.ServeFiles("/assets", assetsBox)
    }

    return app
}

// TestHandler is a test handler
func TestHandler(c buffalo.Context) error {
    return c.Render(200, r.String("Test1234"))
}

func myMiddlewareFunc(config myConfig) buffalo.MiddlewareFunc {
    return func(next buffalo.Handler) buffalo.Handler {
        return func(c buffalo.Context) error {
            c.Logger().Info("Test ", config.value)

            return next(c)
        }
    }
}

因此,@ ttomalak的使用接收方创建方法的方法与以下两种方法一样有效:
    mw := myMiddlewareFunc(myConfig{
        value: "test value",
    })
    app.Use(mw)
    app.Middleware.Skip(mw, TestHandler)


    config := myConfig{
        value: "test value",
    }
    app.Use(myMiddlewareFunc(config))
    app.Middleware.Skip(myMiddlewareFunc(config), TestHandler)

所有方法都需要调用中间件方法。此处显示的方法无法使用:
a.Middleware.Skip(Authorization, HomeHandler, ...)
https://github.com/gobuffalo/buffalo/blob/master/middleware.go#L77

我是新手,但我的感觉是这些方法不符合MiddlewareFunc接口,因此调用它们并获取返回类型buffalo.MiddlewareFunc是使它能够工作的原因。

最佳答案

您需要稳定必需的func,但需要无法传递的其他参数。您可以通过将myConfig设置为myMiddlewareFunc的接收者来更改您的处理方式,这是我的意思:

type myConfig struct {
    value string
}

func (config *myConfig) myMiddlewareFunc() buffalo.MiddlewareFunc {
    return func(next buffalo.Handler) buffalo.Handler {
        return func(c buffalo.Context) error {
            c.Logger().Info("Test ", config.value)

            return next(c)
        }
    }
}


func App() *buffalo.App {
    if app == nil {
        app = buffalo.New(buffalo.Options{
            Env:         ENV,
            SessionName: "_myapp_session",
        })
        // Automatically redirect to SSL
        app.Use(ssl.ForceSSL(secure.Options{
            SSLRedirect:     ENV == "production",
            SSLProxyHeaders: map[string]string{"X-Forwarded-Proto": "https"},
        }))

        if ENV == "development" {
            app.Use(middleware.ParameterLogger)
        }

        // Protect against CSRF attacks. https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)
        // Remove to disable this.
        app.Use(csrf.New)

        // Wraps each request in a transaction.
        //  c.Value("tx").(*pop.PopTransaction)
        // Remove to disable this.
        app.Use(middleware.PopTransaction(models.DB))

        // Setup and use translations:
        var err error
        if T, err = i18n.New(packr.NewBox("../locales"), "en-US"); err != nil {
            app.Stop(err)
        }
        app.Use(T.Middleware())

        c := &myConfig{
            value: "test value",
        }
        app.Use(c.myMiddlewareFunc())
        app.Middleware.Skip(c.myMiddlewareFunc(), TestHandler)


        app.GET("/", HomeHandler)
        app.GET("/test", TestHandler)

        app.ServeFiles("/assets", assetsBox)
    }

    return app
}

关于go - 通过中间件配置时,如何允许Buffalo(gobuffalo)中间件的skip()方法?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48791193/

10-11 06:30
查看更多