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.
- 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 forhttps://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. - 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.