简体   繁体   English

通过中间件配置时,如何允许Buffalo(gobuffalo)中间件的skip()方法?

[英]How do I allow the skip() method for Buffalo (gobuffalo) middleware when I'm passing the middleware config?

I'm trying to create a custom Buffalo (gobuffalo) middleware that accepts config which is working. 我正在尝试创建一个接受配置的自定义Buffalo(gobuffalo)中间件。 The issue is I lose the ability to skip the middleware function with this error: 问题是我无法通过以下错误跳过中间件功能:

actions/app.go:63:22: cannot use myMiddlewareFunc (type func(myConfig) buffalo.MiddlewareFunc) as type buffalo.MiddlewareFunc in argument to app.Middleware.Skip actions / app.go:63:22:在app.Middleware.Skip的参数中不能将myMiddlewareFunc(类型func(myConfig)buffalo.MiddlewareFunc)用作buffalo.MiddlewareFunc类型

The code I've got thus far is: 到目前为止,我得到的代码是:

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)
        }
    }
}

So @ttomalak's method of creating a method with a receiver worked as well as the two methods below: 因此,@ ttomalak的使用接收方创建方法的方法与以下两种方法一样有效:

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

and

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

All ways require calling the middleware method. 所有方法都需要调用中间件方法。 The method shown here can't be used: 此处显示的方法无法使用:

a.Middleware.Skip(Authorization, HomeHandler, ...)

https://github.com/gobuffalo/buffalo/blob/master/middleware.go#L77 https://github.com/gobuffalo/buffalo/blob/master/middleware.go#L77

I'm new to go but my sense of it is that the methods aren't conforming to the MiddlewareFunc interface so calling them and getting the return type buffalo.MiddlewareFunc is what's allowing it to work. 我是新手,但我的感觉是这些方法不符合MiddlewareFunc接口,因此调用它们并获取返回类型buffalo.MiddlewareFunc是使它能够工作的原因。

You need to staisfy required func but your require additional parameters which can't be passed. 您需要稳定必需的func但是需要无法传递的其他参数。 You probably can change how you approach this by making your myConfig as reciever of myMiddlewareFunc , by this I mean: 您可能可以通过将myConfigmyMiddlewareFunc来更改处理此方法的方式,这就是说:

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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM