crystal-community / jwt

JWT implementation in Crystal
MIT License
206 stars 24 forks source link

Unhandled exception: cast from String to Hash(K, V) failed #27

Closed Lukc closed 4 years ago

Lukc commented 4 years ago

Hello,

I used to use the jwt shard for some time and it always worked fine, until a few days ago. Not sure if started doing something wrong or if something got broken?

Test code

require "jwt"

token = JWT.encode "token body", "hello, there", JWT::Algorithm::HS256

pp! JWT.decode token, "hello, there", JWT::Algorithm::HS256

Result

$ crystal test.cr
JWT.decode(token, "hello, there", JWT::Algorithm::HS256) # => Unhandled exception: cast from String to Hash(K, V) failed, at /usr/lib/crystal/json/any.cr:239:5:239 (TypeCastError)
  from /usr/lib/crystal/json/any.cr:239:5 in 'as_h'
  from lib/jwt/src/jwt.cr:72:15 in 'decode'
  from broken?.cr:6:5 in '__crystal_main'
  from /usr/lib/crystal/crystal/main.cr:97:5 in 'main_user_code'
  from /usr/lib/crystal/crystal/main.cr:86:7 in 'main'
  from /usr/lib/crystal/crystal/main.cr:106:3 in 'main'
  from __libc_start_main
  from _start
  from ???
$ 

Environment

$ Crystal 0.32.0 (2019-12-12)

LLVM: 9.0.0
Default target: x86_64-pc-linux-gnu

I did test with Crystal 0.31.1 first and had the same issue.

stakach commented 4 years ago

I've added an explicit error for this case as JWT tokens should be JSON hashes. As per the example in the readme:

require "jwt"
payload = { "foo" => "bar" }
token = JWT.encode(payload, "SecretKey", JWT::Algorithm::HS256)

However I understand that it might be desirable to encode basically anything like a JWT token so you can avoid the cast now, in version 1.4, by skipping validation:

require "jwt"
token = JWT.encode "token body", "hello, there", JWT::Algorithm::HS256
pp! JWT.decode token, "hello, there", JWT::Algorithm::HS256, validate: false

notice the , validate: false I've added to your code example.

Hope this helps.