我对可能是一个简单问题的杂草深感兴趣。我需要通过调用第三方CAS认证服务来包装功能。我使用go-cas来做到这一点,直到我开始添加路由需求之前,它一直有效。我选择了朱利安·施密特(Julien Schmidt)的httprouter,并且我还需要某种方式使其与go-cas一起使用。

如果我没记错的话,我需要使用某种定制设计的中间件从处理程序到处理程序。我认为链式店需要走这样的路:

http.Handler-> func(http.ResponseWriter,* http.Request,httprouter.Params)

...第一个是CAS想要的,第二个是httprouter想要的。但是,我现在迷失了方向,无法做任何事情。

感谢您的任何建议!

在下面的代码中,对...的调用

router.Handler("GET", "/", client.HandleFunc(defaultHandler))

...产生此错误:

“不能在client.HandleFunc的参数中将defaultHandler(类型func(http.ResponseWriter,* http.Request,httprouter.Params)用作func(http.ResponseWriter,* http.Request)类型”

这是无效的代码:
package main

import (
    "fmt"
    "log"
    "net/http"
    "strings"
    "time"

    "github.com/go-cas/cas"
    "github.com/julienschmidt/httprouter"
)

func defaultHandler(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
    if !cas.IsAuthenticated(r) {
        cas.RedirectToLogin(w, r)
    }

    pageID := ps.ByName("pageID")

    type pageModel struct {
        Title    string
        PageID   string
    }

    model := pageModel{
        Title:    "Seminars",
        PageID:    pageID,
    }
    render.ToBrowser(w, "views/index.html", &model)
}


func main() {

    u, _ := url.Parse("https://cas_example_server.com")

    client := cas.NewClient(&cas.Options{
        URL: u,
    })

    router := httprouter.New()

    //This line fails with the message:

    //"Cannot use defaultHandler (type func(http.ResponseWriter, *http.Request, httprouter.Params))
    //as type func(http.ResponseWriter, *http.Request) in argument to client.HandleFunc"

    router.Handler("GET", "/", client.HandleFunc(defaultHandler))

    err := http.ListenAndServe(":8080", router)
    if err != nil {
        panic(err)
    }

}

最佳答案

您的中间件可能使用请求上下文将数据传递给具有不同签名的处理程序:

import (
    "net/http"
    "net/url"

    "github.com/go-cas/cas"
    "github.com/julienschmidt/httprouter"
    "golang.org/x/net/context"
)

func defaultHandler(w http.ResponseWriter, r *http.Request) {
    if !cas.IsAuthenticated(r) {
        cas.RedirectToLogin(w, r)
    }

    ps := r.Context().Value("params").(httprouter.Params)

    // business logic
}


func main() {

    u, _ := url.Parse("https://cas_example_server.com")

    client := cas.NewClient(&cas.Options{
        URL: u,
    })

    router := httprouter.New()

    //This line fails with the message:

    //"Cannot use defaultHandler (type func(http.ResponseWriter, *http.Request, httprouter.Params))
    //as type func(http.ResponseWriter, *http.Request) in argument to client.HandleFunc"

    router.Handler("GET", "/", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
        newContext := context.WithValue(r.Context(), "params", ps)
        r.WithContext(newContext)
        client.HandleFunc(defaultHandler)(w, r)
    })

    err := http.ListenAndServe(":8080", router)
    if err != nil {
        panic(err)
    }

}

更新:
有很多有用的库可以像https://github.com/urfave/negroni这样保存您的http处理程序堆栈

10-07 16:17