dongshiliao7990 2017-09-26 18:53
浏览 49
已采纳

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

I'm deep in the weeds on what's probably a simple problem. I need wrap a func with a call to a third-party CAS authenication service. I'm using go-cas to do that, and it worked until I started adding routing requirements. I chose Julien Schmidt's httprouter, and somehow I need to get that to work with go-cas too.

If I'm not mistaken, I need to use some kind of custom-designed middleware to go from handler to handler. I think the chain needs to go something like this:

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

...the first being what CAS wants, and the second being what httprouter wants. But I'm so lost now that I can't make heads or tails of what to do.

Thanks for any advice!


In the code below, the call to ...

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

... produces this error:

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

Here's the non-working code:

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条回答 默认 最新

  • dongmufen8105 2017-09-27 12:31
    关注

    Your middleware may use request context to pass the data to the handler with different signature:

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

    UPDATE: There are a number of useful libraries to hold your http handlers stack like this https://github.com/urfave/negroni

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 搭建pt1000三线制高精度测温电路
  • ¥15 使用Jdk8自带的算法,和Jdk11自带的加密结果会一样吗,不一样的话有什么解决方案,Jdk不能升级的情况
  • ¥15 画两个图 python或R
  • ¥15 在线请求openmv与pixhawk 实现实时目标跟踪的具体通讯方法
  • ¥15 八路抢答器设计出现故障
  • ¥15 opencv 无法读取视频
  • ¥15 用matlab 实现通信仿真
  • ¥15 按键修改电子时钟,C51单片机
  • ¥60 Java中实现如何实现张量类,并用于图像处理(不运用其他科学计算库和图像处理库))
  • ¥20 5037端口被adb自己占了