2017-10-17 4 views
0

J'utilise auth0 pour l'authentification et j'utilise l'une des méthodes fournies (copiées ci-dessous) pour confirmer le jeton jwt. La solution qu'ils fournissent frappe leur service sur chaque demande à mon serveur, ce qui rend les demandes prennent jusqu'à 1 seconde pour terminer.cache auth0 clé publique

Je tente de mettre en cache la clé publique qui est générée par la méthode qu'ils fournissent mais qui n'a pas de chance. Au début, je pensais que je peux stocker dans Rails.cache mais réalisé la méthode crée un objet OpenSSL, pas une chaîne, et quand j'essaie Rails.cache.write('KEY', openSslObject) et accès avec Rails.cache.fetch('KEY') Je reçois nul retourné

J'ai essayé aussi d'utiliser un bloquer le cache chercher des rails:

cached_jwks_hash = Rails.cache.fetch("JWKS_HASH", expires_in: 10.hours) do 
    get_jwks_hash 
end 

mais toujours obtenir nulle

la méthode get_jwks_hash retourne ci-dessous les éléments suivants: {"key"=>#<OpenSSL::PKey::RSA:0x007fe29c545ef8>}

quelle serait la meilleure façon de mettre en cache ces données? est-il possible de stocker cela dans une variable en mémoire?

def verify(token, jwks_hash) 
    JWT.decode(token, nil, 
       true, # Verify the signature of this token 
       algorithm: 'RS256', 
       iss: "https://#{ENV["AUTH0_DOMAIN"]}/", 
       verify_iss: true, 
       aud: ENV["AUTH0_API_AUDIENCE"], 
       verify_aud: true) do |header| 
     jwks_hash[header['kid']] 
    end 
    end 

    def get_jwks_hash 
    jwks_raw = Net::HTTP.get URI("https://#{ENV["AUTH0_DOMAIN"]}/.well-known/jwks.json") 
    jwks_keys = Array(JSON.parse(jwks_raw)['keys']) 
    Hash[ 
     jwks_keys 
     .map do |k| 
     [ 
      k['kid'], 
      OpenSSL::X509::Certificate.new(
      Base64.decode64(k['x5c'].first) 
     ).public_key 
     ] 
     end 
    ] 
    end 

Répondre

0

Ok, donc après avoir fait des recherches, je vois le problème. La clé n'est pas enregistrée car la méthode rails.cache.fetch utilise un null_store qui ne stocke aucune donnée. Dans mon fichier config/environments/development theres le code suivant:

if Rails.root.join('tmp/caching-dev.txt').exist? 
    config.action_controller.perform_caching = true 
    config.cache_store = :memory_store 
    config.public_file_server.headers = { 
     'Cache-Control' => 'public, max-age=172800' 
    } 
    else 
    config.action_controller.perform_caching = false 
    config.cache_store = :null_store 
    end 

et que je n'avez pas un fichier tmp/caching-dev.txt, le null_store est utilisé. L'avant-dernière ligne peut être mise à jour pour lire

config.cache_store = :memory_store ou n'importe quel type de magasin que vous aimez