waiting-for-dev / devise-jwt

JWT token authentication with devise and rails
MIT License
1.26k stars 130 forks source link

[Question] How do I properly support both no-format and .json in url? #236

Closed mein-beer-hu closed 1 year ago

mein-beer-hu commented 2 years ago

Hello, I am using devise + devise_jwt I am having trouble understanding the right way to support both the formats in url. I did read through the section of "supporting request_formats here: https://github.com/waiting-for-dev/devise-jwt#request_formats

I have the following setup in my devise.rb (initializer folder)

  config.jwt do |jwt|
    jwt.secret =  ENV['DEVISE_JWT_SECRET_KEY']
    jwt.dispatch_requests = [
      ['POST', %r{^/login$}]
    ]
    jwt.revocation_requests = [
      ['DELETE', %r{^/logout$}]
    ]
    jwt.request_formats = {
      user: [nil, :json]  # Is this correct?
    }

    jwt.expiration_time = 5.day.to_i
  end

Expected behavior

Support .json in url as well as no formats

Actual behavior

I am going to pick one URL to help keep this scoped:

When I hit logout.json here is what happens:

  ↳ app/controllers/api/people/sessions_controller.rb:68:in `respond_to_on_destroy'
  TRANSACTION (0.2ms)  BEGIN
  ↳ app/controllers/api/people/sessions_controller.rb:68:in `respond_to_on_destroy'
  User Update (2.7ms)  UPDATE "users" SET "sign_in_count" = $1, "current_sign_in_at" = $2, "last_sign_in_at" = $3, "updated_at" = $4 WHERE "users"."id" = $5  [["sign_in_count", 266], ["current_sign_in_at", "2022-02-12 00:15:19.952937"], ["last_sign_in_at", "2022-02-12 00:15:03.064516"], ["updated_at", "2022-02-12 00:15:19.953450"], ["id", "df2a6186-a671-45f3-8846-00910efedcc2"]]
  ↳ app/controllers/api/people/sessions_controller.rb:68:in `respond_to_on_destroy'
  TRANSACTION (42.0ms)  COMMIT
  ↳ app/controllers/api/people/sessions_controller.rb:68:in `respond_to_on_destroy'
Filter chain halted as :verify_signed_out_user rendered or redirected
Completed 200 OK in 120ms (Views: 0.2ms | ActiveRecord: 55.2ms | Allocations: 26385)

Please observe there is no updates to jwt_denylist table.

Now, if I try logout (no .json in url)

It properly updates the jwt_denylist

*** Above output + and update to jwt_denylist ***

Filter chain halted as :verify_signed_out_user rendered or redirected
Completed 200 OK in 31ms (Views: 0.3ms | ActiveRecord: 11.7ms | Allocations: 5278)

  User Load (0.8ms)  SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2  [["id", "df2a6186-a671-45f3-8846-00910efedcc2"], ["LIMIT", 1]]
  JwtDenylist Load (0.4ms)  SELECT "jwt_denylist".* FROM "jwt_denylist" WHERE "jwt_denylist"."jti" = $1 AND "jwt_denylist"."exp" = $2 LIMIT $3  [["jti", "210d1632-c814-4b98-af7d-9fe3772761b5"], ["exp", "2022-02-17 00:15:03"], ["LIMIT", 1]]
  TRANSACTION (0.5ms)  BEGIN
  JwtDenylist Create (8.6ms)  INSERT INTO "jwt_denylist" ("jti", "exp") VALUES ($1, $2) RETURNING "id"  [["jti", "210d1632-c814-4b98-af7d-9fe3772761b5"], ["exp", "2022-02-17 00:15:03"]]
  TRANSACTION (107.6ms)  COMMIT

Debugging information

Provide following information. Please, format pasted output as code. Feel free to remove the secret key value.

waiting-for-dev commented 2 years ago

Your configuration seems correct in that regard, make sure devise is well set up for an API: https://github.com/waiting-for-dev/devise-jwt/wiki/Configuring-devise-for-APIs

mein-beer-hu commented 2 years ago

One more difference from there is

  devise_for :users, controllers: {
    confirmations: :user_confirmations,
    passwords: :passwords,
    invitations: :invitations,
  }

  devise_scope :user do
    post 'login' => 'api/people/sessions#create', :as => :login
    delete 'logout' => 'api/people/sessions#destroy', :as => :logout
    # post 'register' => 'api/people/registrations#create', :as => :registers
    delete 'delete_account' => 'api/people/registrations#destroy', :as => :delete_account
  end

This is how my routes look like. Maybe I should add { defaults: :json }

waiting-for-dev commented 2 years ago

Did you go through all the guides I linked before? One common issue is overriding controllers beyond making them recognizable by Devise.

mein-beer-hu commented 2 years ago

Yes, I think I also observed that its only the logout path thats partially failing when invoked without .json. For rest of the controllers, with/without json in URL is not causing any issues

waiting-for-dev commented 1 year ago

Closing it, as I don't think there's anything we can fix on our end. Please, feel free to get back if you have any new information.