Home > Blockchain >  JWT.decode is returning nil unless validation is set to false
JWT.decode is returning nil unless validation is set to false

Time:09-30

I'm following the Auth0 blog for decoding a JWT and I'm trying to grab the user information from it.

Create a web token class def self.verify(token)

    decoded_token = JWT.decode(token, nil,
               true, # Verify the signature of this token
               algorithms: 'RS256',
               iss: 'https://YOUR_DOMAIN/',
               verify_iss: true,
               aud: Rails.application.secrets.auth0_api_audience,
               verify_aud: true) do |header|
      jwks_hash[header['kid']]
    end
  end

But when I inspect decoded_token its nil.

Looking at the jwt gem, in decode I see:

# Set password to nil and validation to false otherwise this won't work
decoded_token = JWT.decode token, nil, false

So I changed true to false in the auth0 code and I can see the pertinent user data that I need.

(byebug) decoded_token
[{"email"=>"[email protected]", "iss"=>"https://example.com/", "sub"=>"auth0|123456", "aud"=>["https://example.com", "https://example.auth0.com/userinfo"], "iat"=>123456, "exp"=>123456, "azp"=>"123456abc", "scope"=>"openid profile email"}, {"alg"=>"RS256", "typ"=>"JWT", "kid"=>"abcdefg"}]

I don't fully understand the code, what is happening here. Seems like I would want to keep verification on right?

CodePudding user response:

Your token is invalid. At the very least the issuer (iss) doesn't match (and you've specifically set verify_iss: true) and the expiration claim (exp) is (very far) in the past, which automatically invalidates a JWT.

If you give an invalid token to decode and specify that it should validate its input, it returns nil, per its documentation.

Seems like I would want to keep verification on right?

Yes. You certainly want to reject invalid tokens.

CodePudding user response:

I awarded user229044 with the right answer because they were correct, the token was invalid, but wanted to add context for anyone who may run into something similar.

  1. Check your env vars. The problem turned out to be the string interpolation in json_web_token.rb: iss: "https://#{Rails.application.credentials.auth0[:DOMAIN]}/", and in the domain in the env file also included the full domain (including https://), so JWT.decode was looking for https://https.//... and the issuer was invalid. This was hard to see because the env vars matched my frontend 100% so cross checking those didn't help.
  2. I had littered my call stack with byebugs trying to figure this out which messed with the implicit returns in ruby. The decoded token should be available in your secured_controller.rb as it gets returned implicitly in authorization_service.rb and json_web_token.rb.
  • Related