Отключить CSRF в вызовах API JSON - PullRequest
0 голосов
/ 13 ноября 2018

У меня есть проект веб-сайта.Он использует Go и Gorilla, а также пакеты CSRF для защиты от CSRF.У меня также есть JSON API, который аутентифицируется с использованием JWT-подобного провайдера токенов (внутреннего), поэтому пользователь должен проходить аутентификацию с этим перед отправкой запроса JSON каждый раз.Таким образом, CSRF не является проблемой на стороне JSON.По крайней мере, я так не думаю.

Вот мой код, где я использую NewRouter для веб-путей и Подрутер для / api / v1 / [конечной точки].Если я вызываю конечную точку JSON, выполняющую POST, CSRF включается, и я получаю недопустимый токен Forbidden - CSRF.Я предполагал, что, возможно, у Sub Router не будет промежуточного программного обеспечения для проверки CSRF, связанного с.

router := mux.NewRouter().StrictSlash(false)
router.Path("/").HandlerFunc(myApp.IndexHandler).Methods("GET")

apiRouter := router.PathPrefix("/api").Subrouter()
apiRouter.Path("/dosomething").HandlerFunc(myApp.DoSomethingAPIHandler).Methods("POST", "OPTIONS")

http.ListenAndServe(":8000",
    csrf.Protect(
        []byte("my-long-key-here-redacted"),
        csrf.Secure(false), // Set to false as we offload SSL elsewhere
    )(router)))

Вопрос: Как мне заставить мой API работать с защитой CSRF или без нее?Очевидно, что веб-пути должны быть защищены для защиты сообщений формы.

1 Ответ

0 голосов
/ 13 ноября 2018

Один из вариантов - использовать защиту CSRF только для определенных обработчиков HTTP, а не для защиты всего маршрутизатора.Обратите внимание, что для этого потребуется выполнить преобразование типа на myApp.IndexHandler, чтобы удовлетворить сигнатуру типа для функции, возвращаемой csrf.Protect().

router := mux.NewRouter().StrictSlash(false)

// Instead of protecting your entire router, you can protect specific HTTP
// handlers.
router.Path("/").Handler(
    csrf.Protect(
        []byte("my-long-key-here-redacted"),
        csrf.Secure(false),
    )(http.HandlerFunc(myApp.IndexHandler)),
).Methods("GET")

apiRouter := router.PathPrefix("/api").Subrouter()
apiRouter.Path("/dosomething").HandlerFunc(myApp.DoSomethingAPIHandler).Methods("POST", "OPTIONS")

http.ListenAndServe(
    ":8000",
    router,
)

В качестве альтернативы, вы можете использовать функцию, возвращаемую изcsrf.Protect() для создания собственного промежуточного программного обеспечения с логикой для добавления защиты CSRF только для определенных запросов.Вы можете использовать этот подход, например, чтобы добавить защиту только на конечных точках с префиксом /api, как я сделал в приведенном ниже коде.

protectionMiddleware := func(handler http.Handler) http.Handler {
    protectionFn := csrf.Protect(
        []byte("my-long-key-here-redacted"),
        csrf.Secure(false),
    )

    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // Use some kind of condition here to see if the router should use
        // the CSRF protection. For the sake of this example, we'll check
        // the path prefix.
        if !strings.HasPrefix(r.URL.Path, "/api") {
            protectionFn(handler).ServeHTTP(w, r)
            return
        }

        handler.ServeHTTP(w, r)
    })
}

router := mux.NewRouter().StrictSlash(false)
router.Path("/").HandlerFunc(myApp.IndexHandler).Methods("GET")

apiRouter := router.PathPrefix("/api").Subrouter()
apiRouter.Path("/dosomething").HandlerFunc(myApp.DoSomethingAPIHandler).Methods("POST", "OPTIONS")

http.ListenAndServe(
    ":8000",
    protectionMiddleware(router),
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...