缓存auth0公钥

时间:2017-10-17 13:44:29

标签: ruby-on-rails caching

我使用auth0进行身份验证并使用其提供的方法之一(下面复制)来确认jwt令牌。他们提供的解决方案在我的服务器的每个请求上都会提供服务,这使得请求最多需要1秒才能完成。

我试图缓存由他们提供的方法生成但却没有运气的公钥。起初我以为我可以将它存储在Rails.cache中,但后来意识到该方法创建了一个OpenSSL对象,而不是字符串,当我尝试Rails.cache.write('KEY', openSslObject)并使用Rails.cache.fetch('KEY')访问它时我收到了nil

我还尝试使用带有rails cache fetch的块:

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

但仍然没有

以下get_jwks_hash方法会返回以下内容:{"key"=>#<OpenSSL::PKey::RSA:0x007fe29c545ef8>}

缓存此数据的最佳方法是什么?是否可以将其存储在内存中的变量中?

  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

1 个答案:

答案 0 :(得分:0)

好的,经过研究,我发现问题所在。密钥未保存,因为rails.cache.fetch方法使用的null_store实际上并未存储任何数据。在我的config/environments/development文件中包含以下代码:

  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

由于我没有tmp/caching-dev.txt文件,因此正在使用null_store。倒数第二行可以更新为读取

config.cache_store = :memory_store或您喜欢的任何商店