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.io v2 Changelog #723

Open
DanOnCall opened this issue Dec 19, 2024 · 146 comments
Open

JWT.io v2 Changelog #723

DanOnCall opened this issue Dec 19, 2024 · 146 comments

Comments

@DanOnCall
Copy link
Contributor

DanOnCall commented Dec 19, 2024

🎉 Update: The beta is now complete and we've kickstarted an A/B test for v1 vs v2. We'll continue to iterate on feedback shared on this issue, so please keep it coming. For now, you no longer need to enter any passcode to access v2. If you get v1, clear your cookies, refresh, and if the random algo is on your side, you'll get group B (v2).

TL;DR: Please try out the prototype of JWT.io v2 and share feedback with us any feedback that you may have to help us ship an even better JWT debugger than what we had before:

As mentioned in "The Future of JWT.io", we have been actively working on a new version of the JWT Debugger, and now we have a working prototype that y'all can try out.

Please help us stress test it by using it as you would use JWT.io. We are eager to balance better UI/UX with better design while upholding the most important value proposition of the site: it's a developer tool. Your feedback is critical for us to ship this experience, as we don't want to ship anything that will prevent you from enjoying using this tool. Please reply with your feedback (the good, the bad, and the ugly) or react with emojis--that works too! 🚀

Below is a list of all new features, deprecations, and notable changes (so far) for the migration of JWT.io from v1 to v2.

Notable Changes

New JWT widgets

  • We have divided the JWT Debugger tool into two main widgets, each handling a different JWT operation to provide better error handling and user feedback.
  • A JWT decoder
    • The decoder takes as input a JWT and outputs its decoded header and payload.
    • You can see the decoded output as a JSON object or as a table that includes helpful descriptions, tips, and other metadata about the claims.
      • Time-related claims, such as exp and iat, show you the date in a human-readable format.
      • The decoder now warns you when a JWT has expired.
      • You can input a secret or public key to verify its signature.
      • We have improved communication about the different encodings and formats that secrets and public keys can have, respectively.
      • Secret: UTF-8 and base64url encoding.
      • Public Key: PEM or JWK formats.
    • ✨ The decoder now supports decoding unsecured JWTs.
    • ✨ Decoding and verifying the signature of JWTs signed with the EdDSA (Ed25519) algorithm is now supported.
      • This support is only available on the Firefox and Safari browsers. Learn more about the browsers that support this algorithm here.
      • Chrome has provided experimental support since version 113. The experimental flag #enable-experimental-web-platform-features preference needs to be set to enabled. Learn more.
    • ✨ You can see the decoded header and payload output in a large modal by clicking the resize button next to the copy button.
  • A JWT encoder
    • The encoder takes as input JSON objects for the header and payload.
    • You can input a secret or private key to sign the token, a required step for generating the JWT.
    • We have improved communication about the different encodings and formats that secrets and private keys can have, respectively.
    • Secret: UTF-8 and base64url encoding.
    • Private Key: PEM or JWK formats.
    • The encoder now supports the encoding of unsecured JWTs.
    • ✨ Encoding and signing JWTs with the EdDSA (Ed25519) algorithm is now supported with the same constraints present in the decoder widget.
    • ✨ The encoder shows a warning when the alg claim is not equal to JWT.
  • Both widgets offer better error messages so you can understand why your JWT encoding or decoding is not working and how to fix the issue.
  • Both widgets have utility buttons on some of their inputs and outputs to help you perform common operations:
    • You can copy the content of some inputs and outputs using a button.
    • You can clear the content of inputs with a button click.
    • You can "push" the decoder outputs to be input in the encoder and vice versa through a "sync" button.
    • This is a feature where we need the most feedback, as the widget split is the biggest UI/UX change.
    • The current codebase was not handling errors coherently, and mixing encoding and decoding operations into a single flow was chaotic, leading to swallowed errors or confusing or non-responsive UX.
  • You can choose an option to sync the decoder and encoder widgets.
    • The outputs of the decoder become the inputs of the encoder and vice versa.
    • Errors in the decoder create errors in the encoder and vice versa.
    • This behavior is somewhat similar to what jwt.io v1 does today but it introduces a clear separation layer between decoder and encoder operations to better understand what is triggering an error with the JWT to troubleshoot it more effectively.

Site architecture

  • Perhaps the most important architectural change is migrating the code base from JavaScript with Pug and Express to Next.js with TypeScript.
    • This new stack gave us a multiplier effect to engineer a better UX and underlying JWT-related services.
    • This new stack will help us iterate faster through the application, address feedback faster, and grow its feature set.
  • The query parameter used to filter libraries has been updated from ?language= to ?filter=.
    • Query parameter values have been updated to use safe URL characters.
      • For example, the value for kdb+/Q has been changed to kdb-q.
      • Old query parameters and values are still supported.
  • We have migrated from using URL query parameters to preload JWTs into the JWT decoder to URL fragments.
    • The only support fragment is #token=.
    • Any other legacy query parameter will redirect to that fragment.
  • We crafted the site to support internationalization as we plan to ship a localized version of JWT.io in Japanese next year.
  • ✨ The site is now localized in Japanese.

Design

  • The site now supports a dark and light theme.
  • The hero banner and JWT warning message are much more compact and can be minimized to offer a more streamlined UI suitable for a developer tool.
    • We'd love for you to use JWT.io as much as you need. After a few times, or even after one time, you don't need to stare at the same FYI and warnings about copy-pasting JWTs around the web.
  • Pickers allow you to select the encoding format for the secret and the format for the private/public key.
    • This allows us to provide a better user experience and more insightful error messages.
    • Labels around the pickers provide you with a better context of what it does.
  • ✨ By default, the site selects your theme based on your system's theme preference.
    • However, if you want to use another theme, the site will remember your preference.

User Experience

  • The site remembers your preferences using cookies.
    • Once you minimize a box or pick a decoded presentation, the site will look as such on your next visit or upon refresh.
  • ✨ There are buttons to share feedback or report issues.
  • ✨ The library cards now includes the library name as its title instead of the language/framework.

Content

  • The introduction has a section that explains the difference between validating and verifying a JWT.
  • The introduction has a section that explains the difference between decoding and encoding a JWT.

Deprecations

  • Tooltips about JWT claims have been deprecated for the claims breakdown feature.
    • This change makes it easier for you to access this information when needed.
    • You can hide the description of claims in the decoded output table once you no longer need them.
  • Tooltips for time-related claims (e.g., exp, nbf, iat, auth_time, and updated_at) that show the time in a readable format have been deprecated in favor of showing the time in the claims breakdown tab.
  • The tooltip for weak secrets has been deprecated to show a detailed and helpful error message.
  • The "Share JWT" feature has been deprecated.
  • The "Tokens created" counter has been deprecated.
    • Should we bring this back? It's fun to look at but does not serve any functional purpose.

What's next?

  • Top priority: Improve accessibility and keyboard navigation (WIP).
  • We need to define a process to manage JWT libraries on the directory page.
    • When should we remove a library?
    • We could reflect helpful information to end-users, such as if a repo connected to the library was archived or if it's showing unmaintained signs.
  • I'd like to bring support to the site for encrypted JWTs. Is this something you'd be interested in using directly on the site so we can invest time and resources in it?
  • Would you be okay if the website repo were to become private while a repo to submit JWT libraries remains public?
    • If you scroll to the footer of both jwt.io v1 and v2, you'll notice that we have built several other tools to help developers with identity-related tasks.
    • I have a vision and mission to update and revamp these other tools and connect them via an "app picker" similar to what Google Chrome offers for Google apps; however, they are a mix of private and public repos. Having them all in a single mono-repo would help accelerate the design and engineering process, but that repo would likely need to be private.

Thank you!

We appreciate your usage of jwt.io and all the feedback we have received throughout the years and recently. Working on jwt.io has been the highlight of my time at Auth0 and Okta. I hope that you get to love using this tool as much as we loved building it for you.

fr fr

@imcarlosguerrero

This comment has been minimized.

@DanOnCall

This comment has been minimized.

@ElliotThiebaut

This comment has been minimized.

@EdwardBlair

This comment has been minimized.

@greglearns

This comment has been minimized.

@the-docta

This comment has been minimized.

@achapla

This comment has been minimized.

@rgmz

This comment has been minimized.

@k0rean-rand0m

This comment has been minimized.

@DanOnCall

This comment has been minimized.

@matteokov

This comment has been minimized.

@Aareksio

This comment has been minimized.

@xlab

This comment has been minimized.

@DanOnCall

This comment has been minimized.

@DanOnCall

This comment has been minimized.

@DanOnCall

This comment has been minimized.

@DanOnCall

This comment has been minimized.

@DanOnCall

This comment has been minimized.

@DanOnCall

This comment has been minimized.

@DanOnCall

This comment has been minimized.

@DanOnCall

This comment has been minimized.

@DanOnCall

This comment has been minimized.

@DanOnCall

This comment has been minimized.

@DanOnCall

This comment has been minimized.

@DanOnCall

This comment has been minimized.

@DanOnCall

This comment has been minimized.

@imcarlosguerrero

This comment has been minimized.

@Aareksio

This comment has been minimized.

@imHarshBhatia

This comment has been minimized.

@Hacking-Notes

This comment has been minimized.

@DanOnCall
Copy link
Contributor Author

@jakubboucek Totally! We are working on it. I was out of office today but my teammate has advanced a PR to bring that "partial JWT" back. Once it's live, I'll @ you asking you if you could perhaps help us stress test it. 🙏

@DanOnCall
Copy link
Contributor Author

@denkeni Allowing y'all to switch between versions was something I proposed but was ultimately decided to keep the group assignment random and without option to manually switch. I believe others were able to do so by changing the value of the cookie using the browser dev tools. v1 is control and v2 is variant. Please let me now if that works as a contingency plan 🙏

@DanOnCall
Copy link
Contributor Author

In the effort to scope this tool strictly to handle JWT operation, the logic of v2 adheres strictly to the spec. Now we understand that some of y'all need flexibility to still decode arbitrary base64url strings. The compromise here is that (1) we can decode them but (2) we won't provide user feedback on validation or errors as that logic is for strings that do represent JWTs.

Would this compromise/middle ground work for y'all? cc @bharat-gadde-dev @bsanchezb @mistval

@bsanchezb
Copy link

@DanOnCall , sounds good. As long as the data is decoded I am satisfied and do not care about other possible errors that may arise. After all, I understand that the primary goal is JWT decoding, so I do not expect more from an arbitrary base64url string's decoding.

@Aareksio
Copy link

@DanOnCall

In the effort to scope this tool strictly to handle JWT operation, the logic of v2 adheres strictly to the spec

I was frustrated with this as well. If the tool is a debugger, it should account for common debugging / development scenarios. Just like language server must parse code block that includes a syntax error, JWT debugger should be able to parse as much data as possible from invalid input. That's the use of a debugger - to understand errors, not see unhelpful "Invalid".

The proposed solution (decode what's possible, do not provide validation or errors because token is not a valid JWT) is what current jwt.io does and it should work well. It does work well for my use case :)

I'll be soon offboarding

@hmoratopcs
Copy link

I'll ensure that this feedback is visible to its future owner(s) 🙏

Thank you very much.

What I can recommend in the meantime is to fork v1 as it's open source and run it locally if the v2 experience is decreasing your productivity. Apologies about that 🙏

Can you point me to the commit/tag/branch of v1, please?

(Quick question: Would a keyboard shortcut to navigate encoder<>decoder improve your experience?)

Not really, thanks.

@Vision70
Copy link

How can I access the old version?

@FDuda354
Copy link

please delete this version and back v1

@j1m-renwick
Copy link

j1m-renwick commented Feb 20, 2025

This version is IMO uglier, unnecessarily complicated due to the separate encoding / decoding sections, and is too strict and doesn't support previous usage - it might be technically true that "A key of 256 bits or larger MUST be used with HS256 as specified on RFC 7518.", but why can't I specify a smaller dummy one for testing a JWT in lower environments? I know this technically is possible, so let me take the risk if I want. IMO this should be a warning, and not block the functionality itself.

(Sorry, I appreciate the effort to improve it, but I just don't feel this is better than v1)

@CyberMew
Copy link

CyberMew commented Feb 20, 2025

Can we have an option to use the old one?

I am trying to use it to see details about a JWS, and instead of showing me the header claims it says my JWS payload is not in JSON format. Even if the payload is in plain text format, it should be showing as much information as possible instead of completely not parsing it. This did not happen in the old version. The new version is so bad that I had to come here to post this... Warnings about specs are nice but this is a developer-centric tool, older features that worked previously should still be maintained.

Is it also possible for us to run a local copy easily? Anyone knows the last working commit and if it is easy to get it up and running?

@Aareksio
Copy link

To anyone looking to get back to v1, as explained by Dan above:

ELI5: Clear website cookies,
Techy: Replace "ab-variant" cookie value with "control"

@Vision70 @FDuda354 @CyberMew

@shobe7
Copy link

shobe7 commented Feb 20, 2025

Why does the JWT payload must represent JSON, old version worked with any payload :/

@Lanny
Copy link

Lanny commented Feb 20, 2025

My most used flow was: paste token, edit claims, copy new token. I've tested the sync feature and am glad it's there, but now the flow is: paste token, switch to the Encoder tab, find claims because they move to the left, edit claims, copy new token. I understand that separation of concerns can be a good thing for many users, but for me it's a pain. If there are no plans to improve this, any chance that I can stick to v1 forever? Thank you for such a great tool.

Same workflow here. I have a shortcut to schlep a jwt out of cookies and open jwt.io with it. In development I often turn signature verification off, so it was a really nice workflow of "open jwt.io, immediately edit token, paste newly generated token back into ". This is kind of broken with v2. I can sorta reproduce this if I resign my token with the specific secret "a-string-secret-at-least-256-bits-long", open jwt.io, and toggle the "sync with encoder" thing twice but that's... kind of a headache

@twocs
Copy link

twocs commented Feb 21, 2025

Why does the JWT payload must represent JSON, old version worked with any payload :/

I also prefer that the invalid JWT is decoded with warnings. The original version runs the code to the best of its ability without being fragile to errors. I prefer a screwdriver that doesn't refuse to work as a pry bar or gasket scraper. This is the v1 behaviour for a payload that's not json:
Image

@Lanny
Copy link

Lanny commented Feb 21, 2025

Is the source for the new version available anywhere? Master seems to be the old version, and unlike the old version there doesn't appear to be a github link anywhere (other than to this issue). I'd love to pitch in a PR.

@Lanny
Copy link

Lanny commented Feb 21, 2025

Also for those wanting to stick with the v1 experience, I took the advice here:

What I can recommend in the meantime is to fork v1 as it's open source

and have hosted it at https://jwt.lannysport.net/ . If others aren't ready to switch and forcing yourself onto a particular side of an A/B test isn't your speed (I link into the debugger from internal tooling, so I can't really control the A/B assignment for people following those links) then feel free to use it. I removed the supplemental pages and a good chunk of the UI including the auth0 logo, the purpose of which is to avoid misrepresenting the fork as as official or endorsed by auth0. The intent here is simply to make the old version available until v2 satisfies my usecase, and I would love to start using v2 at that point.

@JamesMaroney
Copy link

This is looking and behaving great! I really appreciate your writeup on the changes and reasonings too, that's excellent.

The one thing that I noticed right off the bat that the old decoder handled that this one doesn't seem to, is oftentimes I'll copy a JWT from the browser tools, and the easiest way to do that ends up grabbing the surrounding quotes. The v1 debugger seemed to account for this and stripped those off. It seems with v2, we have to paste, then remove the quotes. It was super nice when it just handled it.

Thanks for this tool! It really makes my day so much easier.

@samad-scs
Copy link

This is great!!!

The only thing which needs to be considered is the surrounding quotes when pasting a jwt.

Previous UI/UX handled that which this new UI doesnt, but other than that, Great job!

@bhavya-syncglob
Copy link

Old one is much better

@Lemonsix
Copy link

The old one is better, it just needed some darkmode. But this new one is like overloaded with stuff. Maybe moving the encoder to another view or something

@frankracis-litmos
Copy link

Using base64url for the secret is an odd choice. You'd never send your secret in a web request, and I would expect most configurations to store this value in normal base64 encoding (which is what the old site used).

@DanOnCall
Copy link
Contributor Author

DanOnCall commented Feb 21, 2025

Folks, our Github admins have enabled discussions :) We'll start linking to that section for users to leave us feedback in a way that we can address y'all directly and more personally. We appreciate all the passion and enthusiasm that y'all have for jwt.io in general. We value every comment, whether it's constructive criticism to improve the v2 or praise.

As I mentioned before, our focus changed by end of last year and we have limited time to iterate now. I am also off-boarding from this project, which will happen in the middle of March. It's been a pleasure to serve as the lead of this initiative. I'll be around to help fix any critical issues such as errors or bugs.

However, you have my commitment that we'll do our best to implement the important features you've have mentioned from v1 into v2 and that you'll have v1 available to access or run locally as you see fit.

v2 is a separate project running on a different host from another repo. It's a full rewrite of jwt.io using TypeScript and Next.js. We'll update the README soon but these are the instructions on how you can run v1 locally. The most recent commit will work fine. (My teammate Christian created these instructions for y'all)

  • Make sure that you run these commands using Node v16.x.x.
  • Clone the project:
git clone [email protected]:jsonwebtoken/jsonwebtoken.github.io.git
  • Make the project directory your current directory:
cd jsonwebtoken.github.io
  • Install required dependencies:
npm install
  • Build the project:
npm run build
  • Run the development server:
npm run start

Image

@Aareksio
Copy link

@DanOnCall Running locally is not the solution any of the commenters is seeking.

While the A/B lasts, how about adding easy switch between the versions in the top announcement bar (where link to this issue is) to let users chose. Most sites doing new versions allow switching to old UI exactly to track what is still missing / giving users a chance to keep their workflow if it broke in v2.

You can then track use of this link to determine what users actually need. Version is already controlled by cookie, it shouldn't be difficult to add.

Maybe it is just the vocal minority, but the issue is far from filled with praise, most comments are the complaints about broken workflows. An easy way to go back, while you keep v1 alive, would save all these people while better solution is worked on.

@Ansis100
Copy link

While the A/B lasts, how about adding easy switch between the versions in the top announcement bar (where link to this issue is) to let users chose. Most sites doing new versions allow switching to old UI exactly to track what is still missing / giving users a chance to keep their workflow if it broke in v2.

That would be great. I've been using the browser's Private mode to force it to load the old version but the A/B gods have decided that my Private will now also use v2.

@DanOnCall
Copy link
Contributor Author

@Aareksio 👍 Switching groups was one of the suggestions I presented earlier to our leaders. I'll be sure to bring it up again. We already have the schematic on how to deploy that change. If it's approved, it'll go live. I'll keep y'all in the loop.

Thanks for your proactive feedback since the start of the beta, @Aareksio. You've helped us a lot answering questions on the issue and also giving us key feedback.

@byron-okta
Copy link
Contributor

Hi everyone! Thanks for sharing your feedback; it helps us improve the new version.

I'm stepping in as an interim maintainer. I'll collaborate to help address your feedback and prioritize it with our leaders.

For those who have already been assigned to JWT v2 and need to switch back to v1 to continue using your existing workflows while we iterate on your feedback, you can switch back to v1 by clicking the "Switch to v1" button in the navigation bar.

We've implemented the feature to automatically remove any leading "bearer " part when pasting "Bearer token..." as input to facilitate its usage. From the previous comments, I recall that you @andreas-lundgren-qlucore asked for this feature. Please let us know if you run into any issues!

Additionally, we're currently iterating on the feedback to support decoding JWTs signed with other algorithms beyond those currently supported by the tool, as well as decoding Base64Url pieces of JWTs. Instead of showing an error, the tool will display the decoded output, making it more flexible.

Thanks

@byron-okta
Copy link
Contributor

Hi, folks

I wanted to share a quick update: we've implemented the old support for decoding JWTs signed with algorithms beyond those currently supported by the tool and decoding Base64Url pieces of JWTs in JWT v2. Additionally, the JWT Decoder and JWT Encoder widgets are now in sync by default; you no longer need to click the "Sync" button.

Thanks again for sharing your proactive feedback. Let us know if you run into any issues!

@lokirb1995
Copy link

lokirb1995 commented Mar 4, 2025

I’m experiencing an issue with the new JWT.io UI in Firefox. It is defaulted with the old UI, but sometimes when the new UI does appear, it intermittently shows the error: “Sorry, an error occurred.” (screenshot attached).

Image

This issue is seen inconsistently only when new UI changes are displayed on Firefox browser for few seconds. Is this a known bug ?

@christiansamaniego-okta
Copy link
Contributor

I’m experiencing an issue with the new JWT.io UI in Firefox. It is defaulted with the old UI, but sometimes when the new UI does appear, it intermittently shows the error: “Sorry, an error occurred.” (screenshot attached).

Image

This issue is seen inconsistently only when new UI changes are displayed on Firefox browser for few seconds. Is this a known bug ?

Hi @lokirb1995 👋
This issue has been fixed in our latest release and is now live. If you are still experiencing issues, please feel free to reach out again, and we'll continue to investigate.

If you have other issues or suggestions for enhancements, please feel free to open a new discussion, and we'll do our best to address them.

Christian S.

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

No branches or pull requests