Skip to content

Instantly share code, notes, and snippets.

@twopoint718
Last active December 19, 2022 20:46
Show Gist options
  • Save twopoint718/f638155936ae9c88cf70765c7ecae9b8 to your computer and use it in GitHub Desktop.
Save twopoint718/f638155936ae9c88cf70765c7ecae9b8 to your computer and use it in GitHub Desktop.
Build a JWT on the command line
#! /usr/bin/env ruby
require 'optparse'
require 'base64'
require 'json'
require 'openssl'
require 'set'
options = {}
OptionParser.new do |parser|
parser.banner = "Usage: jwt.rb [options]"
parser.on("-sSECRET", "--secret=SECRET", "Secret to sign the JWT") do |v|
options[:secret] = v
end
parser.on("-pPAYLOAD", "--payload=PAYLOAD", "JSON-formatted payload for token") do |v|
options[:payload] = v
end
end.parse!
required_args = Set[:secret, :payload]
missing = required_args - options.keys
if !missing.empty?
raise("Missing: #{missing.to_a.join(', ')}")
end
header = Base64.strict_encode64({
"alg" => "HS256",
"typ" => "JWT"
}.to_json)
header.chomp!(header[/=+$/])
payload = Base64.strict_encode64(
JSON.parse(options[:payload])
.merge({
# Put any default payload here (ex):
"iat" => Time.now.to_i
})
.to_json
)
payload.chomp!(payload[/=+$/])
signature = Base64.strict_encode64(
OpenSSL::HMAC.digest(
OpenSSL::Digest.new('sha256'),
options[:secret],
header + '.' + payload
)
)
signature.chomp!(signature[/=+$/])
token = [
header,
payload,
signature
].join('.')
puts token
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment