waiting-for-dev / devise-jwt

JWT token authentication with devise and rails

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Can't nadle JWT::DecodeError exception on Rails 7

coins-black opened this issue · comments

Hi guys!

I'm using Rails 7 App and want to handle JWT::DecodeError. In my app/controllers/application_controller.rb i wrote:

   rescue_from JWT::DecodeError do |jwt_exception|
	render_error 	message: 'jwt error', 
			http_status: 	:bad_request, 
			error_code: 	'100011'
  end

but still have this in response:

{
  "status": 500,
  "error": "Internal Server Error",
  "exception": "#<JWT::DecodeError: Invalid segment encoding>",
  "traces": { ...

Can anybody help, why exceptions as ActionController::UnknownFormat, ActionDispatch::Http::Parameters::ParseError, and other handles well, but JWT::DecodeError doesn't. Thanks!

Probably that's because the exception is raised in a Rack middleware before reaching the Rails stack. You can try to debug your issue around this line:

https://github.com/waiting-for-dev/warden-jwt_auth/blob/09c78d747cab802180e4d93a14cc33cf313e27d0/lib/warden/jwt_auth/strategy.rb#L20.

I've got the same problem on Rails 6.1.4

solved by adding custom middleware
thanks

@coins-black Could you share your solution?

@coins-black Could you share your solution?

Rails 7.0.0

lib/middleware/catch_rack_errors.rb

module Middleware
  class CatchRackErrors

    def initialize(app)
      @app = app
    end         # def initialize


    def call(env)

      begin

        @app.call(env)

      rescue JWT::DecodeError => e

        return [
          401, 
          { "Content-Type" => "application/json" },
          [ 
            { 
              message: 'JWT token is invalid or expired',
              error_code: '100011'
            }.to_json 
          ]
        ]

      end       # rescue

    end         # def call

  end           # class
end             # module

config/application.rb

module AppName
  class Application < Rails::Application
    ...
    # Load my own middleware
    Dir[Rails.root.join('lib', 'middleware', '*.{rb}')].each { |file| require file }

    # Add own middleware for catching errors
    config.middleware.use Middleware::CatchRackErrors
    ...

I had the same problem and this solution worked for me.

It seems that it is a common problem. Dou you think this solution could be provided natively by devise-jwt? Does it make sense?

Does anybody know what has changed between Rails 6 & 7 for it now be an issue?

Actually I'm not sure if it was introduced recently because I'm using Rails 6 before having devise-jwt. I'm sorry. 😕