-
Notifications
You must be signed in to change notification settings - Fork 376
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
First idea of a extendable JWT decoder #434
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
module JWT | ||
module Extension | ||
module ClassMethods | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. JWT::Extension::ClassMethods has no descriptive comment |
||
def decode_payload(&block) | ||
@decode_payload_block = block | ||
end | ||
|
||
def decode(payload, options = {}) | ||
segments = ::JWT::Decode.new(payload, | ||
options.delete(:key), | ||
true, | ||
create_decode_options(options)).decode_segments | ||
{ | ||
header: segments.last, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. JWT::Extension::ClassMethods#decode refers to 'segments' more than self (maybe move it to another class?) |
||
payload: segments.first | ||
} | ||
end | ||
|
||
private | ||
|
||
def create_decode_options(given_options) | ||
::JWT::DefaultOptions::DEFAULT_OPTIONS.merge(decode_payload_proc: @decode_payload_block).merge(given_options) | ||
end | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'securerandom' | ||
|
||
RSpec.describe JWT::Extension do | ||
subject(:extension) do | ||
Class.new do | ||
include JWT | ||
end | ||
end | ||
|
||
let(:secret) { SecureRandom.hex } | ||
let(:payload) { { 'pay' => 'load'} } | ||
let(:encoded_payload) { ::JWT.encode(payload, secret, 'HS256') } | ||
|
||
describe '.decode' do | ||
it { is_expected.to respond_to(:decode) } | ||
|
||
context 'when nothing special is defined' do | ||
it 'verifies a token and returns the data' do | ||
expect(extension.decode(encoded_payload, key: secret)).to eq(header: { 'alg' => 'HS256' }, payload: payload) | ||
end | ||
end | ||
|
||
context 'when a decode_payload block is given' do | ||
before do | ||
extension.decode_payload do |_header, raw_payload, _signature| | ||
payload_content = JWT::JSON.parse(JWT::Base64.url_decode(raw_payload)) | ||
payload_content['pay'].reverse! | ||
JWT::Base64.url_encode(JWT::JSON.generate(payload_content)) | ||
end | ||
end | ||
|
||
it 'lets before decode process the raw payload before verifying' do | ||
expect(extension.decode(encoded_payload, key: secret)).to eq(header: { 'alg' => 'HS256' }, payload: {'pay' => 'daol'}) | ||
end | ||
end | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
JWT::Decode#decode_and_parse_payload calls '@options[:decode_payload_proc]' 2 times
Read more about it here.