Route-specific Middlewares with Negroni

huangapple go评论71阅读模式
英文:

Route-specific Middlewares with Negroni

问题

我有一个使用httprouter和negroni的Web服务器。用户通过外部OAuth登录到该系统。我们将令牌保存到加密的会话中,以指示他们是否已登录。我想使用一个中间件来验证该令牌是否存在,如果不存在,则将用户重定向到登录页面。我希望排除某些路由不使用身份验证中间件。negroni的README中有一个使用gorilla mux的示例,但我无法理解如何在httprouter中实现可扩展性。类似于我的服务器设置如下:

router := httprouter.New()
router.GET("/login", Login) // 不需要身份验证
router.GET("/", Index)  // 需要身份验证

s := negroni.Classic()

s.Use(sessions.Sessions("example-web-dev", cookiestore.New([]byte("some garbage"))))
s.Use(authenticator.Get())
s.UseHandler(router)

其中/login是我不想要求通过中间件进行授权的路由,/是需要授权的路由。authenticator.Get()是我的身份验证处理函数,其中的内容与问题无关。

如何将authenticator.Get()应用于/而不应用于/login?请注意,除了/login之外,还将有其他几个“公共”路由和许多其他需要授权的路由。

一些链接:

英文:

I have a web server using httprouter and negroni. Users log into this system through external OAuth. We save the token to the encrypted session which indicates whether or not they are logged in. I would like to use a middleware to verify whether or not this token exists, and then kick the user back to the login page if it does not. I want to exclude some routes from using the authentication middleware. There is an example in the negroni README of doing this with gorilla mux, but I can't quite get my head around doing this scalably with httprouter. Something similar to my server setup is below:

router := httprouter.New()
router.GET("/login", Login) // auth not required
router.GET("/", Index)  // auth required

s := negroni.Classic()

s.Use(sessions.Sessions("example-web-dev", cookiestore.New([]byte("some garbage"))))
s.Use(authenticator.Get())
s.UseHandler(router)

Where /login is a route I do not want to require authorization through the middleware and / is. authenticator.Get() is my authentication handler func with contents I don't think are relevant to the question.

How can I apply authenticator.Get() to / but not /login? Keeping in mind that there will be several other "public" routes alongside /login and many other gated routes as well.

Some links:

答案1

得分: 4

我最终能够理解这个过程。解决方案是为每个单独的路由创建新的negroni.Negroni实例。在上面的例子中:

router := httprouter.New()
router.Handler("GET", "/login",
               negroni.New(negroni.HandlerFunc(loginHandler)))
router.Handler("GET", "/",
               negroni.New(authenticator.Get(),
               negroni.HandlerFunc(indexHandler)))

server := negroni.Classic()
server.UseHandler(router)
server.Use(sessions.Sessions("example-web-dev",
           cookiestore.New([]byte("some secret"))))
server.Run(":3000")

loginHandlerindexHandler都需要具有以下方法签名:

func(http.ResponseWriter, *http.Request, http.HandlerFunc)

在给定的示例中,所有路由都将使用negroni.Classic()提供的中间件和添加到serversessions中间件,但只有/将使用我在authenticator.Get()中创建的中间件。

英文:

I was eventually able to wrap my brain around this process. The solution is to create new negroni.Negroni instances for each individual route. In the case above:

router := httprouter.New()
router.Handler("GET", "/login",
               negroni.New(negroni.HandlerFunc(loginHandler)))
router.Handler("GET", "/",
               negroni.New(authenticator.Get(),
               negroni.HandlerFunc(indexHandler)))

server := negroni.Classic()
server.UseHandler(router)
server.Use(sessions.Sessions("example-web-dev",
           cookiestore.New([]byte("some secret"))))
server.Run(":3000")

loginHandler and indexHandler will both need to have this method signature:

func(http.ResponseWriter, *http.Request, http.HandlerFunc)

With the given example, all routes will utilize the middleware provided by negroni.Classic() and the sessions middleware added to server, but only / will use the middleware I created in authenticator.Get().

答案2

得分: -1

如果使用httprouter,可以通过调用router.Lookup函数来获取参数。这是我所做的:

_, params, _ := router.Lookup("GET", req.URL.Path)

其中router是httprouter.Router的一个实例。

英文:

if using httprouter, params can be retrieved by calling the router.Lookup function. Here is what I did:

_, params, _ :=  router.Lookup("GET", req.URL.Path)

where router is an instance of httprouter.Router

huangapple
  • 本文由 发表于 2015年2月10日 03:55:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/28418168.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定