Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Decode a JWT via command line
# will not work in all cases, see https://gist.github.com/angelo-v/e0208a18d455e2e6ea3c40ad637aac53#gistcomment-3439904
function jwt-decode() {
sed 's/\./\n/g' <<< $(cut -d. -f1,2 <<< $1) | base64 --decode | jq
}
JWT=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
jwt-decode $JWT
@invertigo

This comment has been minimized.

Copy link

@invertigo invertigo commented May 30, 2019

why not just cut -d"." -f1,2 <<< $1 | sed 's/\./\n/g' | base64 --decode | jq?

@lukaslihotzki

This comment has been minimized.

Copy link

@lukaslihotzki lukaslihotzki commented Jan 23, 2020

With just jq: jq -R 'split(".") | .[1] | @base64d | fromjson' <<< "$JWT"

@micklove

This comment has been minimized.

Copy link

@micklove micklove commented Mar 3, 2020

@lukaslihotzki, nice work :)

With just jq: jq -R 'split(".") | .[1] | @base64d | fromjson' <<< "$JWT"
@philpennock

This comment has been minimized.

Copy link

@philpennock philpennock commented Sep 2, 2020

JWTs use base64url encoding, which neither jq nor base64 (from GNU coreutils) can handle. So the above examples all work some of the time, not reliably.

@angelo-v

This comment has been minimized.

Copy link
Owner Author

@angelo-v angelo-v commented Sep 2, 2020

Valid point @philpennock. Do you have a reliable solution?

@lukaslihotzki

This comment has been minimized.

Copy link

@lukaslihotzki lukaslihotzki commented Sep 2, 2020

Just replace the characters? jq -R 'gsub("-";"+") | gsub("_";"/") | split(".") | .[1] | @base64d | fromjson'

@seva-ramin

This comment has been minimized.

Copy link

@seva-ramin seva-ramin commented Sep 26, 2020

JWTs use base64url encoding, which neither jq nor base64 (from GNU coreutils) can handle. So the above examples all work some of the time, not reliably.

@philpennock is correct. Here is my solution in a shell script:

#!/bin/bash

# pad base64URL encoded to base64
paddit() {
  input=$1
  l=`echo -n $input | wc -c`
  while [ `expr $l % 4` -ne 0 ]
  do
    input="${input}="
    l=`echo -n $input | wc -c`
  done
  echo $input
}

# read and split the token and do some base64URL translation
read jwt
read h p s <<< $(echo $jwt | tr [-_] [+/] | sed 's/\./ /g')

h=`paddit $h`
p=`paddit $p`

# assuming we have jq installed
echo $h | base64 -d | jq
echo $p | base64 -d | jq
@philpennock

This comment has been minimized.

Copy link

@philpennock philpennock commented Sep 28, 2020

Oh, I never spoke up, sorry: I use shell around Perl because Perl had the easiest access to base64url when I last went looking, but I was impressed by the solution from @lukaslihotzki using gsub inside jq as being the solution with the fewest additional dependencies.

@eum602

This comment has been minimized.

Copy link

@eum602 eum602 commented Oct 13, 2020

I was also trying to decode a JWT token. I could decode a JWT with:

for line in `echo $JWT | tr "." "\n"`; do echo $line | base64 --decode | jq  && echo;done
@danmactough

This comment has been minimized.

Copy link

@danmactough danmactough commented Dec 22, 2020

@seva-ramin's script is fantastic, but just a small bug: tr [+_] [-/] should be tr [-_] [+/]

@seva-ramin

This comment has been minimized.

Copy link

@seva-ramin seva-ramin commented Dec 23, 2020

@seva-ramin's script is fantastic, but just a small bug: tr [+_] [-/] should be tr [-_] [+/]

Ugh! what a silly mistake! @danmactough, Thank you for catching that. I have updated my post.

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