Skip to content
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

JWT::Encode refactorings, alg and exp related bugfixes #293

Merged
merged 1 commit into from
Jan 21, 2019

Conversation

anakinj
Copy link
Member

@anakinj anakinj commented Jan 20, 2019

Spent a little time fixing and simplifying (at least in my mind) things related to the encoding process of the JWT token. Also base64 and JSON operations were moved to its own class.

Comments are appreciated!

@anakinj
Copy link
Member Author

anakinj commented Jan 20, 2019

I think this fixes #282 also

@excpt excpt self-assigned this Jan 21, 2019
@excpt excpt added this to the Version 2.2.0 milestone Jan 21, 2019
@excpt excpt self-requested a review January 21, 2019 10:22
@excpt excpt removed their assignment Jan 21, 2019
Copy link
Member

@excpt excpt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the contribution. 👍

@excpt excpt merged commit 0ad5436 into jwt:master Jan 21, 2019
anakinj added a commit to anakinj/ruby-jwt that referenced this pull request Jan 21, 2019
excpt added a commit that referenced this pull request Jan 21, 2019
# Base64 helpers
class Base64
class << self
def url_encode(str)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you really want to add two more methods to the public API of this gem that handle Base64 encoding? This kind of thing should probably be kept private.

# JWT::Encode module
module JWT
# Encoding logic for JWT
class Encode
attr_reader :payload, :key, :algorithm, :header_fields, :segments
ALG_NONE = 'none'.freeze
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't nil be a better representation of none?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is something related to creating a JWT without a signature. none is the algorithm the JWA spec defines as "Unsecured JWS"

ALG_NONE = 'none'.freeze
ALG_KEY = 'alg'.freeze
EXP_KEY = 'exp'.freeze
EXP_KEYS = [EXP_KEY, EXP_KEY.to_sym].freeze
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be better off refactoring to use a HashWithIndifferentAccess

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did not spend that much time focusing on this payload validation, think that it belongs somewhere else than the Encode class. I think #287 is a more elegant way to handle this.

@jamesstonehill
Copy link
Contributor

Sorry to be late to the comments. My main concern here is that this adds methods to the public API of this gem that then need to be maintained to adhere to semantic versioning. Base64 encoding and JSON parsing might might be necessary parts of the JWT generation process, but it's better if you don't give users a way to rely on this behaviour.

@anakinj
Copy link
Member Author

anakinj commented Jan 22, 2019

Thanks for the feedback.

The idea was not to add more public APIs for the GEM. It was more to have the Base64 and JSON related methods used in this gem in the same place. This would for example allow easier monkey patching the JSON handling to use some other JSON framework than the default, not saying monkey patching is the way to go:)

The helper methods could as well be in a JWT::InternalUtils module, but they would be as publicly available as they are now and as they were before.

AFAIK there is no good way in Ruby to hide GEM internals, in theory all the classes and methods in a gem is free to be used anywhere, but i suppose they are not considered public because you can access them?

What would you suggest doing to make this clearer?

@jamesstonehill
Copy link
Contributor

@anakinj yeah totally agree, Ruby doesn't have a good way of handling these situations. I guess we could take it as a given that only methods on the "JWT" constant are part of the API but I think that's a bit limiting and inevitably someone will ignore that and if they do they are susceptible to breaking changes in minor or even patch updates.

If you wanted to make these private your options would be to use private_constant or to keep this functionality as private instance methods.

You're comment about monkey patching is interesting. However, as you also hint at, I think that if this becomes a feature requirement there are better ways to implement this like a json_parser configuration option.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants