Я использую собственный обработчик журналирования на своем веб-сервере Go, например:
func main() {
// ... Set up everything
router = mux.NewRouter()
router.Handle("/apilookup",
raven.Recoverer(
jwtMiddleware.Handler(
http.HandlerFunc(
doApiLookup)))).Methods("GET")
loggedRouter := handlers.CustomLoggingHandler(os.Stdout, router, writeLog)
http.ListenAndServe(listenAddr, loggedRouter)
}
В функции writeLog
я создал собственную версию Gorilla handlers.LoggingHandler
, которая регистрируетмного дополнительной информации.
Одна вещь, которую я хотел бы сделать, это войти в систему пользователя для аутентифицированных запросов.Пользователи проходят аутентификацию на этом сервере, используя JWT
(используя заголовок Authorization: Bearer ...
).Я использую Auth0 go-jwt-middleware
для анализа токена и установки его значения в контексте запроса.
Я попытался зарегистрировать адрес электронной почты пользователя (одно из утверждений в JWT), например:это основано на документации промежуточного программного обеспечения:
func writeLog(writer io.Writer, params handlers.LogFormatterParams) {
// ... SNIP
// If we can't identify the user
username := "-"
if userJwt := params.Request.Context().Value("user"); userJwt != nil {
claims := userJwt.(*jwt.Token).Claims.(*jwtClaims)
username = claims.Email
}
// ... SNIP
}
Проблема в том, что username
всегда является начальным значением -
, а не ожидаемым значением от JWT.
Путем добавления log.Printf("%+v\n", params.Request.Context())
выше if
, я вижу, что context
на самом деле не содержит проанализированных здесь данных JWT.
Насколько я могу судить, причина, по которой это не работает, заключается в том, что промежуточное ПО создаетновый Request
с обновленным контекстом, поэтому его может видеть только промежуточное программное обеспечение, находящееся ниже по цепочкеПоскольку промежуточное программное обеспечение для ведения журналов находится над промежуточным программным обеспечением JWT, оно не имеет такого же контекста.
Я знаю, что могу повторно проанализировать JWT в обработчике ведения журнала (поскольку у меня есть доступ ко всем заголовкам),но это, кажется, требует много времени для ведения журнала.
Есть ли лучший способ сделать это, который позволит мне иметь доступ к этим данным там, где я хочу?