bploetz/versionist

Devise issue after integrating versionist - "Authentication required for Sign In action"

tacticiankerala opened this issue · 3 comments

We integrated 'versionist' gem for path based versioning for our APIs. After integrating versionist we found that only default sign in/ sign up/password reset urls(Eg: /users/sign_in) are working. The same actions for different versions were giving issues(Eg: /v1/users/sign_in).

We were able to identify that this issue was caused because of the scope. For example, if we are using v1 API then the scope received in Sessions#create is found to be v1_user.

Here is the set up we used,

Routes

 api_version(:module => "v1", :path => {:value => "v1"}) do
   devise_for :users, :controllers => { 
      :registrations => 'v1/registrations',
      :sessions => 'v1/sessions',
      :passwords => 'v1/passwords'
    }   
end

And we got the auth_options inside Sessions#create as

{:scope => :v1_user, :recall => "sessions#new"}

We tried overriding the scope to :user and everything started working.

Similar issues we faced in registrations and passwords controller, where the devise parameters found to be nil for constructing the resource.

Here is our dependencies,

rails (3.2.13)
devise (2.2.3)
versionist (1.2.1)

Right now we have overridden all the required devise actions, is there a better solution to this problem?

When you say "The same actions for different versions were giving issues(Eg: /v1/users/sign_in)", what exactly happened? Did you get an error? Did it do something unexpected?

Any chance you could distill this down to a skeleton example app which exhibits the problem and throw it up on github somewhere where I can take a look?

I am also experiencing this problem. With the following route

  namespace :api, defaults: { format: 'json' } do
    api_version(module: 'V1',
                header: { name: 'Accept', value: 'application/vnd.example.com; version=1' },
                path: { value: 'v1' }) do
      scope as: :member, path: :m, module: :member do
        devise_for :customers,
                   path: '',
                   path_names: {
                     sign_in: 'login',
                     sign_out: 'logout',
                     registration: 'signup'
                   }
      end
    end
  end

I get { scope: :api_v1_member_customer ... }. It should only be { scope: :customer ... }

After reading the source code, I think I have to avoid using the path based versioning to get what I want.

I can successfully authenticate with the following setup.

  scope :member, module: :office do
    scope :api, module: :api, defaults: { format: :json } do
      api_version( module: 'V1', header: { name: 'Accept', value: 'application/vnd.example.v1+json' }) do
        devise_for :customers
      end
    end
  end

This is the json request with header Accept: application/vnd.example.v1+json

{
"customer": { "email": "...", "password": "..." } 
}