jwk = JWT :: JWK.import(keyHash)*** ArgumentError异常:无效的base64

时间:2020-07-24 23:05:44

标签: ruby-on-rails jwt jwk apple-login

我正在尝试进行后端Apple登录,并且看起来不错,直到行jwk = JWT::JWK.import(keyHash)总是返回错误无效的base64。我正在使用gem jwt 2.2.1和Ruby 2.2.4

begin
  header_segment = JSON.parse(Base64.decode64(jwt.split(".").first))
  alg = header_segment["alg"]
  kid = header_segment["kid"]

  apple_response = Net::HTTP.get(URI.parse(GET_PK_APPLE_URL))
  apple_certificate = JSON.parse(apple_response)

  keyHash = ActiveSupport::HashWithIndifferentAccess.new(apple_certificate["keys"].select {|key| key["kid"] == kid}[0])

  jwk = JWT::JWK.import(keyHash)

  token_data = JWT.decode(jwt, jwk.public_key, true, {algorithm: alg})[0]

  if token_data.has_key?("sub") && token_data.has_key?("email") && userIdentity == token_data["sub"]
    puts "Name: " + name + " is validated."
    login_or_create_user('apple')
  else
    render_error
  end
rescue StandardError => e
  render_error
end

1 个答案:

答案 0 :(得分:0)

我发现了问题,jwt gem有一个openssl依赖关系,openssl需要一个来自Ruby的更实际的版本,由于其他原因,我现在无法更改我的Ruby版本,因此我需要更改代码以获取JWK,使用```JWT :: JWK.import(keyHash)````。我还需要使用UrlSafeBase64 gem。

begin      
  header_segment = JSON.parse(Base64.decode64(jwt.split(".").first))
  alg = header_segment["alg"]
  kid = header_segment["kid"]

  apple_response = Net::HTTP.get(URI.parse(LOGIN_APPLE_URL))
  apple_certificate = JSON.parse(apple_response)

  keyHash = ActiveSupport::HashWithIndifferentAccess.new(apple_certificate["keys"].select {|key| key["kid"] == kid}[0])      
  key = OpenSSL::PKey::RSA.new
  key.e = OpenSSL::BN.new(UrlSafeBase64.decode64(keyHash["e"]), 2)
  key.n = OpenSSL::BN.new(UrlSafeBase64.decode64(keyHash["n"]), 2)
                  
  token_data = JWT.decode(jwt, key, true, {algorithm: alg})[0]
  
  if token_data.has_key?("sub") && token_data.has_key?("email") && userIdentity == token_data["sub"]        
    login_or_create_user('apple')
  else
    render_error
  end
rescue StandardError => e
  render_error
end