2017-09-26 6 views
0

Je suis au fond des herbes sur ce qui est probablement un problème simple. J'ai besoin de boucler une fonction avec un appel à un service d'authentification CAS tiers. J'utilise go-cas pour cela, et cela a fonctionné jusqu'à ce que je commence à ajouter des exigences de routage. J'ai choisi httprouter de Julien Schmidt, et d'une manière ou d'une autre, j'ai besoin de travailler avec go-cas. Si je ne me trompe pas, j'ai besoin d'utiliser une sorte de middleware conçu sur mesure pour passer du gestionnaire au gestionnaire. Je pense que la chaîne doit aller quelque chose comme ceci:Enchaînement CAS middleware et le routage httprouter()

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

... le premier étant ce que CAS veut, et le second étant ce que veut httprouter. Mais je suis tellement perdu maintenant que je ne peux pas faire la tête ou la queue de quoi faire.

Merci pour votre conseil!


Dans le code ci-dessous, l'appel à ...

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

... produit cette erreur:

« ne peut pas utiliser DefaultHandler (type func (http.ResponseWriter, * http .Request, httprouter.Params)) en tant que type func (http.ResponseWriter, * http.Request) en argument client.HandleFunc »

est ici le code non-travail:

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

} 

Répondre

0

Votre middleware peut utiliser le contexte de demande de transmettre les données au gestionnaire avec signature différente:

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

} 

MISE À JOUR: Il y a un certain nombre de bibliothèques utiles pour tenir vos gestionnaires http pile comme celui-ci https://github.com/urfave/negroni