ruby -e "require 'openssl'; require 'base64'; OpenSSL::PKey::RSA.generate(2048).tap { |p| puts '', 'PRIVATE RSA KEY (URL-safe Base64 encoded, PEM):', '', Base64.urlsafe_encode64(p.to_pem), '', 'PUBLIC RSA KEY (URL-safe Base64 encoded, PEM):', '', Base64.urlsafe_encode64(p.public_key.to_pem) }"
config/management_api_v1.yml
at Peatio.You should give the ID to the key and put it in variable called keychain
.
The variable keychain
in config/management_api_v1.yml
should look like:
keychain:
backend-1.mycompany.example:
algorithm: RS256
value: 'BACKEND_1_PUBLIC_KEY_IN_PEM_FORMAT_BASE64_URLSAFE_ENCODED'
backend-2.mycompany.example:
algorithm: RS256
value: 'BACKEND_2_PUBLIC_KEY_IN_PEM_FORMAT_BASE64_URLSAFE_ENCODED'
The value
is public key from URL-safe Base64 encoded PEM from the first step.
The algorithm
is signature algorithm you prefer.
You can customize JWT verification options using variable jwt
in config/management_api_v1.yml
:
jwt:
verify_jti: true
verify_aud: true
exp_leeway: 180
The documentation is available at jwt repository.
The config/management_api_v1.yml
already includes good docs for this step. You can find it at the bottom near variable scopes
.
The JWT provider can use Ruby Gem jwt-multisig
for generating JWT with multiple signatures.
You should store private keys (ID, value, algorithm) somewhere in your application.
To generate JWS use the JWT::Multisig.generate_jwt(payload, private_keychain, algorithms)
.
In private_keychain
you need to put private key from URL-safe Base64 encoded PEM from the first step.
The output from this example with serialized JWT will be save in data.json.
Example:
require 'openssl'
require 'jwt-multisig'
require 'base64'
require 'json'
payload = {
exp: 1922830281, # Put here all the JWT claims.
data: { foo: 'bar', baz: 'qux' } # Put here all the data your API action expects.
}
# You can choose what signatures the JWT should include.
private_keychain = {
:'backend-1.mycompany.example' => OpenSSL::PKey.read(Base64.urlsafe_decode64('BACKEND_1_PRIVATE_KEY_IN_PEM_FORMAT_BASE64_URLSAFE_ENCODED')),
:'backend-2.mycompany.example' => OpenSSL::PKey.read(Base64.urlsafe_decode64('BACKEND_2_PRIVATE_KEY_IN_PEM_FORMAT_BASE64_URLSAFE_ENCODED'))
}
algorithms = {
:'backend-1.mycompany.example' => 'RS256',
:'backend-2.mycompany.example' => 'RS256'
}
jwt = JWT::Multisig.generate_jwt(payload, private_keychain, algorithms)
Kernel.puts JSON.dump(jwt) # The output will include serialized JWT.
# Save your JWT in data.json
File.open('./data.json','w') do |f|
f.write(jwt.to_json)
end
The documentation for this method is available at rubydoc.info.
The source code for jwt-multisig
is available at GitHub.
The example JWT is available at jwt-multisig source code.
With next example you can make request with ruby Faraday client library or make request with curl. This request will return empty array if you don't have any deposits on the platform.
Example:
require 'json'
require 'faraday'
require 'faraday_middleware'
# Read and save your JWT from data.json
data = File.read('./data.json')
# Create HTTP request with ruby Faraday client library
module Faraday
class Connection
alias original_run_request run_request
def run_request(method, url, body, headers, &block)
original_run_request(method, url, body, headers, &block).tap do |response|
response.env.instance_variable_set :@request_body, body if body
end
end
end
end
def http_client
Faraday.new(url: @root_api_url) do |conn|
conn.request :json
conn.response :json
conn.adapter Faraday.default_adapter
end
end
# The output will include request response
Kernel.puts http_client
.public_send(:post,'http://localhost:3000/management_api/v1/deposits', data)
.body
Make request with curl.
curl -v -H "Accept: application/json" -H "Content-Type: application/json" -d @jwt.json http://localhost:3000/management_api/v1/deposits