Это плохая идея для кэширования auth0 JWK
Я использую auth0, и у меня есть два клиента (ios, реагировать) и Go Backend API, использующий go-auth0.
Я проследил за документацией и сделал Verify
метод, который выглядит так:
func Verify(handle httprouter.Handle) httprouter.Handle {
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
auth0Domain := viper.GetString("auth0.issuer")
audience := []string{viper.GetString("auth0.audience")}
client := auth0.NewJWKClient(auth0.JWKClientOptions{URI: auth0Domain + ".well-known/jwks.json"}, nil)
configuration := auth0.NewConfiguration(client, audience, auth0Domain, jose.RS256)
validator := auth0.NewValidator(configuration, nil)
_, err := validator.ValidateRequest(r)
if err != nil {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusUnauthorized)
json.NewEncoder(w).Encode(map[string]string{"error": "Unauthorized"})
return
}
handle(w, r, p)
}
}
К сожалению, я замечаю, что первая проверка занимает ~400 мс, а последующие - ~50 мс.
Однако, если я инициализирую структуру с полем для валидатора, перенесу весь установочный код в Initialize()
, тогда это займет всего ~1 мс:
func Verify(handle httprouter.Handle) httprouter.Handle {
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
_, err := a.validator.ValidateRequest(r)
if err != nil {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusUnauthorized)
json.NewEncoder(w).Encode(map[string]string{"error": "Unauthorized"})
return
}
handle(w, r, p)
}
}
Это плохая идея? Я только что узнал о JWK сегодня и смотрю на код auth0, кажется, они создают кеш, но я не совсем понимаю, как он работает.
Может кто-нибудь, пожалуйста, дайте мне знать, если перемещение конфигурации в структуру и использование ее валидатора - это хорошая идея?
ОБНОВИТЬ
Для этого у auth0 есть встроенный метод! Вот пример:
auth0.NewJWKClientWithCache(auth0.JWKClientOptions{URI: a.issuer + ".well-known/jwks.json"}, nil, auth0.NewMemoryKeyCacher(time.Duration(10)*time.Second, 5))
Используйте этот метод, чтобы он кешировал для вас!:)
1 ответ
Почти наверняка должно быть безопасно кэшировать объект клиента, и в целом это обычно является хорошей идеей. ("Создайте одного клиента и используйте его повторно" - это хорошее общее правило.)
Насколько я понимаю, ключи подписи для JWT обычно действительны в течение нескольких месяцев, если не дольше. ( В документации Auth0 отмечается, что в ее документах JWKS всегда есть только один ключ, но он будет выдавать подписанные токены все время, поэтому ключи должны быть действительны в течение некоторого времени.) RFC 7517 не определяет никаких параметров, связанных с истечением времени, для либо JWKS, либо отдельный JWK, и я думаю, что лучше всего использовать обычные элементы управления HTTP-кэшированием на конечной точке JWKS, чтобы периодически обновлять его, но не так часто.