英文:
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
之外,还将有其他几个“公共”路由和许多其他需要授权的路由。
一些链接:
- https://github.com/codegangsta/negroni
- https://github.com/codegangsta/negroni/issues/25
- http://godoc.org/github.com/codegangsta/negroni
- http://godoc.org/github.com/julienschmidt/httprouter
英文:
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")
loginHandler
和indexHandler
都需要具有以下方法签名:
func(http.ResponseWriter, *http.Request, http.HandlerFunc)
在给定的示例中,所有路由都将使用negroni.Classic()
提供的中间件和添加到server
的sessions
中间件,但只有/
将使用我在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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论