链接CAS中间件和httprouter()路由

时间:2017-09-26 18:53:06

标签: go middleware

我对这可能是一个简单问题的杂草很深。我需要通过调用第三方CAS身份验证服务来包装一个func。我正在使用go-cas来做到这一点,直到我开始添加路由要求。我选择了Julien Schmidt的httprouter,不知怎的,我还需要让它与go-cas一起工作。

如果我没弄错的话,我需要使用某种自定义设计的中间件来处理从处理程序到处理程序。我认为链条需要像这样:

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

......第一个是CAS想要的,第二个是httprouter想要的。但是我现在迷失了,因为我无法做出正面或反面的事情。

感谢您的任何建议!

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

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

...产生此错误:

“不能使用defaultHandler(类型为func(http.ResponseWriter,* http.Request,httprouter.Params))作为client.HandleFunc”

的参数中的类型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)
    }

}

1 个答案:

答案 0 :(得分:1)

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

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

}

<强>更新 有许多有用的库来保存您的http处理程序堆栈,如https://github.com/urfave/negroni