Как применить промежуточное ПО для маршрутов горилл / муксов - PullRequest
1 голос
/ 03 апреля 2019

У меня есть эта основная функция в файле main.go внутри основного каталога

func main() {
    log.Printf("Server started")

    router := sw.NewRouter()
    manager := manage.NewDefaultManager()
    manager.SetAuthorizeCodeTokenCfg(manage.DefaultAuthorizeCodeTokenCfg)

    manager.MustTokenStorage(store.NewMemoryTokenStore())

    clientStore := store.NewClientStore()
    manager.MapClientStorage(clientStore)

    srv := server.NewDefaultServer(manager)
    srv.SetAllowGetAccessRequest(true)
    srv.SetClientInfoHandler(server.ClientFormHandler)
    manager.SetRefreshTokenCfg(manage.DefaultRefreshTokenCfg)

    srv.SetInternalErrorHandler(func(err error) (re *errors.Response) {
        log.Println("Internal Error:", err.Error())
        return
    })

    srv.SetResponseErrorHandler(func(re *errors.Response) {
        log.Println("Response Error:", re.Error.Error())
    })

    router.HandleFunc("/oauth2/token", func(w http.ResponseWriter, r *http.Request) {
        srv.HandleTokenRequest(w, r)
    })

    router.HandleFunc("/credentials", func(w http.ResponseWriter, r *http.Request) {
        clientId := uuid.New().String()[:8]
        clientSecret := uuid.New().String()[:8]
        err := clientStore.Set(clientId, &models.Client{
            ID:     clientId,
            Secret: clientSecret,
            Domain: "http://localhost:9094",
        })
        if err != nil {
            fmt.Println(err.Error())
        }

        w.Header().Set("Content-Type", "application/json")
        json.NewEncoder(w).Encode(map[string]string{"CLIENT_ID": clientId, "CLIENT_SECRET": clientSecret})
    })

    log.Fatal(http.ListenAndServe(":8000", router))
}

Приведенные ниже функции находятся в разных файлах в подкаталоге основного файла как

* maindir* subdir

// Функция в handler.go в subdir

func protecteduri(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("Hello, I'm protected"))
}

// Эта функция в middleware.go в subdir

func validateToken(f http.HandlerFunc, srv *server.Server) http.HandlerFunc {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        _, err := srv.ValidationBearerToken(r)
        if err != nil {
            http.Error(w, err.Error(), http.StatusBadRequest)
            return
        }

        f.ServeHTTP(w, r)
    })
}

И мои маршруты находятся вrouter.go в поддиректории как

type Route struct {
    Name        string
    Method      string
    Pattern     string
    HandlerFunc http.HandlerFunc
}

type Routes []Route

func NewRouter() *mux.Router {
    router := mux.NewRouter().StrictSlash(true)
    for _, route := range routes {
        var handler http.Handler
        handler = route.HandlerFunc
        handler = Logger(handler, route.Name)

        router.
            Methods(route.Method).
            Path(route.Pattern).
            Name(route.Name).
            Handler(handler)
    }

    return router
}

func Index(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello World!")
}

var routes = Routes{
    {
        "Index",
        "GET",
        "/",
        Index,
    },

    {
        "protecteduri",
        strings.ToUpper("Get"),
        "/protected",
        protecteduri,
    },
}

Мой вопрос: как применить функцию «validateToken» (промежуточное ПО) к маршрутам в router.go?Функция заключается в проверке токена доступа в сообщении запроса перед вызовом функций-обработчиков.

Я изменил промежуточное программное обеспечение на приведенное ниже, но оно работает, только если функция-обработчик "/ protected" находится в главной функции.У меня много обработчиков, и я не хочу помещать их все в main.go.

func ValidateToken(srv *server.Server) func(http.Handler) http.Handler {
    return func(next http.Handler) http.Handler {
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            notAuth := []string{"/oauth2/token", "/credentials"} //List of endpoints that doesn't require auth
            requestPath := r.URL.Path                            //current request path

            //check if request does not need authentication, serve the request if it doesn't need it
            for _, value := range notAuth {

                if value == requestPath {
                    next.ServeHTTP(w, r)
                    return
                }
            }
            _, err := srv.ValidationBearerToken(r)
            if err != nil {
                http.Error(w, err.Error(), http.StatusBadRequest)
                return
            }

            next.ServeHTTP(w, r)
        })
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...