1

The devise-jwt gem documentation says that if session storage is enabled, you have to skip it for jwt auth. It says that you should set on devise.rb:

config.skip_session_storage = [:http_auth, :params_auth]

And you should disable :database_authenticatable. This part I quite don't understood. If in my User model, I remove :database_authenticatable, my route configured for login becomes unavailable:

ActionController::RoutingError (No route matches [POST] "/login"):

User.rb

class User < ApplicationRecord
  rolify role_join_table_name: 'public.user_roles'
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable

  # devise :database_authenticatable,
  devise :registerable,
         :recoverable,
         :rememberable,
         :validatable,
         :jwt_authenticatable,
         jwt_revocation_strategy: Devise::JWT::RevocationStrategies::Null
end

devise.rb

config.skip_session_storage = %i[http_auth params_auth]

routes.rb

Rails.application.routes.draw do
  # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html

  devise_for :users, defaults: { format: :json },
                     path: '',
                     path_names: {
                       sign_in: 'login',
                       sign_out: 'logout',
                       registration: 'signup'
                     },
                     controllers: {
                       sessions: 'users/sessions',
                       registrations: 'users/registrations'
                     }
end

What should I do to keep session, but not for jwt auth?

Samuel
  • 259
  • 3
  • 15
  • Hi @Samuel, I guess you are using the following gem https://github.com/waiting-for-dev/devise-jwt. I have used the same few days back. you don't have to remove `:database_authenticatable` from the model. just change the config file `config.skip_session_storage` In a project I have to keep both session and jwt. In that case I have to add `Rails.application.config.session_store :cookie_store` in session_store.rb config file and in application_controller for `json` request had to add`'protect_from_forgery with: :null_session if request.format.json?` – Syed Samiuzzaman Aug 22 '20 at 04:34
  • I used another solution, that I posted.. Later I'll try yours. – Samuel Aug 25 '20 at 20:05
  • I had the same issue. My solution was in the devise-jwt documentation.I used `self.skip_session_storage = [:http_auth, :params_auth]` on my non-API user models, so I don't skip it altogether. – alexts Sep 30 '20 at 07:43

1 Answers1

2

Well, after adapting the solution I found in this article https://blog.siliconjungles.io/devise-jwt-with-sessions-hybrid, here's the answer:

monkeypatch: config/initializers/warden/proxy.rb

module Warden
  class Proxy
    def user(_argument = {})
      if request.format.json?
        return nil
      end
    end
  end
end

And you must have separated routes for api auth and default behavior:

routes.rb

namespace :api do
    namespace :v1 do
      devise_scope :user do
        post 'auth/signup', to: 'registrations#create'
        post 'auth/signin', to: 'sessions#create'
        delete 'auth/signout', to: 'sessions#destroy'
      end
    end
  end

  devise_for :users
Samuel
  • 259
  • 3
  • 15