<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Axioms</title>
    <description>The latest articles on DEV Community by Axioms (@axioms).</description>
    <link>https://dev.to/axioms</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F1790%2F936dc770-63f2-4264-90f7-310d963d10ad.png</url>
      <title>DEV Community: Axioms</title>
      <link>https://dev.to/axioms</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/axioms"/>
    <language>en</language>
    <item>
      <title>Introducing JWT Debugger App</title>
      <dc:creator>Abhishek Tiwari</dc:creator>
      <pubDate>Fri, 29 May 2020 16:58:12 +0000</pubDate>
      <link>https://dev.to/axioms/introducing-jwt-debugger-app-2alo</link>
      <guid>https://dev.to/axioms/introducing-jwt-debugger-app-2alo</guid>
      <description>&lt;p&gt;&lt;a href="https://tools.ietf.org/html/rfc7519" rel="noopener noreferrer"&gt;JSON Web Token&lt;/a&gt; is a compact yet URL-safe token primarily used for OAuth 2 and OpenID based authentication and authorization. A JWT token represents a set of claims as a JSON object that is encoded in a JSON Web Signature (JWS) structure.&lt;/p&gt;

&lt;h2&gt;
  
  
  JWT Token
&lt;/h2&gt;

&lt;p&gt;A JWT token is made of three URL-safe portions header, payload, and signature separated by period ('.') characters. Each component contains a base64url-encoded value. For instance, the following string represents a JWT token&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1czNvcmphczc5bDAzOHBrMWJwNmoxZCIsIm5hbWUiOiJKb2huIERvZSIsImp0aSI6Ijc4ZjRnMWpkam5naTBpMzJveGtuZCIsImV4cCI6MTU5MDc2OTE1OH0.rP0Ykkr1jjzErb14OAeNTlCSSGpuKQaxRa2hO3-2Olc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Decoding a token
&lt;/h2&gt;

&lt;p&gt;When you decode a JWT token you get a JSON header and JSON payload. The overall token decoding process is really straightforward. You take the first portion, Base64url decode it and remove any line breaks, whitespace, or other additional characters which gives you header. You take the second portion and Base64url decode it and remove any line breaks, whitespace, or other additional characters which gives you payload.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Token Header decoded from eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;alg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;HS256&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;typ&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;JWT&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// Token Payload decoded from eyJzdWIiOiJ1czNvcmphczc5bDAzOHBrMWJwNmoxZCIsIm5hbWUiOiJKb2huIERvZSIsImp0aSI6Ijc4ZjRnMWpkam5naTBpMzJveGtuZCIsImV4cCI6MTU5MDc2OTE1OH0&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sub&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;us3orjas79l038pk1bp6j1d&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;John Doe&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;jti&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;78f4g1jdjngi0i32oxknd&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;exp&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1590769158&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Token validation
&lt;/h2&gt;

&lt;p&gt;Validation of the token requires signing key or secrete used to create the signature portion of the token. Signing algorithm is described by &lt;code&gt;alg&lt;/code&gt; claim the token header. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If the signing algorithm belongs the family of asymmetrical algorithms i.e. Rivest–Shamir–Adleman (RSA) or Elliptic Curve Digital Signature Algorithm (ECDSA) then you will need the public version of the private key used for token signing. The public key can be in JSON Web Key (JWK) format or PEM format. If you are using an OpenID Connect compliant authorizations server then the public side of JWK keys are served by a JSON Web Key Set (JWKS) endpoint. A JWKS endpoint returns a set of keys which contains the one or more public keys.&lt;/li&gt;
&lt;li&gt;If the signing algorithm belongs to the family of symmetrical algorithms HMAC (sometimes expanded as either keyed-hash message authentication code or hash-based message authentication code) you will need the shared key or secret used to sign the token.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is an example of &lt;a href="https://www.googleapis.com/oauth2/v3/certs" rel="noopener noreferrer"&gt;JWKS endpoint&lt;/a&gt; of Google OAuth 2 server. JWKS endpoint may return more than one public key so you identify relevant key matching the &lt;code&gt;kid&lt;/code&gt; parameter of token header and JWK key.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"keys"&lt;/span&gt;&lt;span class="p"&gt;:[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
         &lt;/span&gt;&lt;span class="nl"&gt;"e"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"AQAB"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
         &lt;/span&gt;&lt;span class="nl"&gt;"alg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"RS256"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
         &lt;/span&gt;&lt;span class="nl"&gt;"use"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"sig"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
         &lt;/span&gt;&lt;span class="nl"&gt;"n"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"qx9oubekMS3x-mmgPJOUeoPJH9aoYwlDfElkRk2XfQnRmsfbxVc8Gna6V8avfWpBcXuyTMkJ4_hmk4Ra3x4KMwpQ3XVZGtFvP2PwTHKbtf47if-gVsh5PZlHovKOS1ixTnagfidzBGpnwAGGSyrIDSVOxPC6GcOIxWtJ56AZ6kcHtI9zGO4AE8T8-TXEgIkUfby-AQCFxzlXDsA_zxWbjka0gscAqiYESB5JLjMrxNWwEPhlvIRO7LospdwYTjZteLAAC5OEWPMlxI6laSB9TzPWLHMsNNEe6_YOylp2sMSwslOb9FFsP5KVaVdBBLwHwFf7ncVaHExFqhwTHIoS8Q"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
         &lt;/span&gt;&lt;span class="nl"&gt;"kty"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"RSA"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
         &lt;/span&gt;&lt;span class="nl"&gt;"kid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"960a7e8e8341ed752f12b186fa129731fe0b04c0"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
         &lt;/span&gt;&lt;span class="nl"&gt;"n"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"zK8PHf_6V3G5rU-viUOL1HvAYn7q--dxMoUkt7x1rSWX6fimla-lpoYAKhFTLUELkRKy_6UDzfybz0P9eItqS2UxVWYpKYmKTQ08HgUBUde4GtO_B0SkSk8iLtGh653UBBjgXmfzdfQEz_DsaWn7BMtuAhY9hpMtJye8LQlwaS8ibQrsC0j0GZM5KXRITHwfx06_T1qqC_MOZRA6iJs-J2HNlgeyFuoQVBTY6pRqGXa-qaVsSG3iU-vqNIciFquIq-xydwxLqZNksRRer5VAsSHf0eD3g2DX-cf6paSy1aM40svO9EfSvG_07MuHafEE44RFvSZZ4ubEN9U7ALSjdw"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
         &lt;/span&gt;&lt;span class="nl"&gt;"kty"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"RSA"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
         &lt;/span&gt;&lt;span class="nl"&gt;"kid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"fb8ca5b7d8d9a5c6c6788071e866c6c40f3fc1f9"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
         &lt;/span&gt;&lt;span class="nl"&gt;"e"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"AQAB"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
         &lt;/span&gt;&lt;span class="nl"&gt;"alg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"RS256"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
         &lt;/span&gt;&lt;span class="nl"&gt;"use"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"sig"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, the use of JWKS endpoint for token validation is recommended as it is safe and does not require sharing of the secret key between parties.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use a JWT Debugger
&lt;/h2&gt;

&lt;p&gt;If you are a developer working with JWT tokens then most likely you use a debugger tool to decode and validate your token. &lt;a href="https://jwt.io/" rel="noopener noreferrer"&gt;JWT.io&lt;/a&gt; is probably one of the most popular out there. JWT.io is an amazing tool but if you are working with sensitive tokens probably you want to avoid pasting them online which is why we created a cross-platform interactive &lt;a href="https://jwtdebugger.app/" rel="noopener noreferrer"&gt;JWT Debugger App&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fk2klmq70lzg29dfzj3mz.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fk2klmq70lzg29dfzj3mz.jpg" alt="JWT Debugger App Web Version with PWA Support" width="800" height="437"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With &lt;a href="https://jwtdebugger.app/" rel="noopener noreferrer"&gt;JWT Debugger App&lt;/a&gt;, use the web version as a progressive web app or install desktop apps for Mac, Window, and Linux. More importantly, [JWT Debugger App] supports token validation using both JWKS Endpoint and PEM/Secret Keys. JWT.io and many other JWT tools currently don't support JWKS Endpoint based token validation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4u8d0git9lr1u4svev8w.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4u8d0git9lr1u4svev8w.jpg" alt="JWT Debugger App Desktop Version" width="800" height="461"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://jwtdebugger.app/" rel="noopener noreferrer"&gt;JWT Debugger App&lt;/a&gt; itself is &lt;a href="https://github.com/axioms-io/axioms-jwt-debugger" rel="noopener noreferrer"&gt;open-source&lt;/a&gt; and if you find any issues or like to add a feature just open a &lt;a href="https://github.com/axioms-io/axioms-jwt-debugger/issues" rel="noopener noreferrer"&gt;Github ticket&lt;/a&gt; and we will love to help.&lt;/p&gt;

</description>
      <category>jwt</category>
      <category>opened</category>
      <category>oauth2</category>
      <category>json</category>
    </item>
  </channel>
</rss>
