Class: IAPServer::JWTTools
- Inherits:
-
Object
- Object
- IAPServer::JWTTools
- Defined in:
- lib/iap/jwttools.rb
Class Method Summary collapse
- .generate ⇒ Object
-
.generate_token(key, kid, iss, bid) ⇒ Object
秘钥串、秘钥ID、Issuer ID、bundle id.
- .good_signature(jws_token) ⇒ Object
- .header(jws_token) ⇒ Object
- .payload(jws_token) ⇒ Object
Class Method Details
.generate ⇒ Object
9 10 11 12 13 14 15 16 17 |
# File 'lib/iap/jwttools.rb', line 9 def self.generate config = IAPServer::AppStoreConfig.default_config raise "获取秘钥信息失败,请检查。" if config.nil? key, kid, iss, bid = config['key'], config['kid'], config['iss'], config['bid'] # fix key key = key.split("\\n").join("\n") if key.include?("\\n") generate_token(key, kid, iss, bid) end |
.generate_token(key, kid, iss, bid) ⇒ Object
秘钥串、秘钥ID、Issuer ID、bundle id
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/iap/jwttools.rb', line 20 def self.generate_token(key, kid, iss, bid) # JWT Header header = { "alg": "ES256", # 固定值 "kid": kid, # private key ID from App Store Connect "typ": "JWT" # 固定值 } iat = Time.new # JWT Payload payload = { "iss": iss, # Your issuer ID from the Keys page in App Store Connect "aud": "appstoreconnect-v1", # 固定值 "iat": iat.to_i, # 令牌生成时间,UNIX时间单位,秒 "exp": iat.to_i + 60 * 60, # 令牌失效时间,60 minutes timestamp "nonce": UUIDTools::UUID..to_s, # An arbitrary number you create and use only once "bid": bid # Your app's bundle ID } ecdsa_key = OpenSSL::PKey::EC.new key # JWT token token = JWT.encode payload, ecdsa_key, algorithm='ES256', header_fields=header token end |
.good_signature(jws_token) ⇒ Object
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/iap/jwttools.rb', line 45 def self.good_signature(jws_token) realpath = File.("#{File.dirname(__FILE__)}/../../assets/AppleRootCA-G3.cer") raw = File.read "#{realpath}" apple_root_cert = OpenSSL::X509::Certificate.new(raw) parts = jws_token.split(".") decoded_parts = parts.map { |part| Base64.decode64(part) } header = JSON.parse(decoded_parts[0]) # puts "Header:#{decoded_parts[0]}" # puts "Payload:#{decoded_parts[1]}" cert_chain = header["x5c"].map { |part| OpenSSL::X509::Certificate.new(Base64.decode64(part))} return false unless cert_chain.last == apple_root_cert for n in 0..(cert_chain.count - 2) return false unless cert_chain[n].verify(cert_chain[n+1].public_key) end begin decoded_token = JWT.decode(jws_token, cert_chain[0].public_key, true, { algorithms: ['ES256'] }) !decoded_token.nil? rescue JWT::JWKError false rescue JWT::DecodeError false end end |
.header(jws_token) ⇒ Object
79 80 81 82 83 |
# File 'lib/iap/jwttools.rb', line 79 def self.header(jws_token) parts = jws_token.split(".") decoded_parts = parts.map { |part| Base64.decode64(part) } decoded_parts[0] end |
.payload(jws_token) ⇒ Object
73 74 75 76 77 |
# File 'lib/iap/jwttools.rb', line 73 def self.payload(jws_token) parts = jws_token.split(".") decoded_parts = parts.map { |part| Base64.decode64(part) } decoded_parts[1] end |