使用Devise和简单令牌身份验证的子域身份验证

时间:2015-01-12 14:41:24

标签: ruby-on-rails authentication devise

我无法弄清楚如何正确地对我的api进行子目录。我想让它住在api.mydomain.com。我已在主机文件中添加了127.0.0.1 api.mydomain.com。 我一直坚持如何构建身份验证模块,以及如何让它实际运行。

我将DeviseSimple Token Authentication宝石一起使用。

我的控制器文件夹结构如下:

├── controllers
    ├── api
    │   ├── api_controller.rb
    │   └── v1
    │       ├── emails_controller.rb
    │       ├── entries_controller.rb
    │       ├── exception_controller.rb
    │       ├── registrations_controller.rb
    │       ├── sessions_controller.rb
    │       └── timelines_controller.rb
    ├── application_controller.rb
    ├── concerns

我的路线计划:

namespace :api, path: '/', constraints: {subdomain: 'api'} do
      namespace :v1 do
        devise_for :users, :skip => [:sessions, :registrations, :passwords]

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

        resources :timelines do
          resources :entries
        end
    end
  end

我的自定义SessionsController定义为:

class API::V1::SessionsController < Devise::SessionsController
   ...
end

我的自定义注册控制器也是如此。 但是在运行我的测试时:

it 'creates a new user with correct credentials' do
            post 'http://api.mydomain.com:3000/v1/register', format: :json, :user => {email: 'user@test.com', password: 'TestPass123', password_confirmation: 'TestPass123', username: 'testuser'}

            ...
end

我收到以下错误:

Failure/Error: post 'http://api.mydomain.com:3000/v1/register', format: :json, :user => {email: 'user@test.com', password: 'TestPass123', password_confirmation: 'TestPass123', username: 'testuser'}
 AbstractController::ActionNotFound:
   Could not find devise mapping for path "/v1/register".
   This may happen for two reasons:

   1) You forgot to wrap your route inside the scope block. For example:

     devise_scope :user do
       get "/some/route" => "some_devise_controller"
     end

   2) You are testing a Devise controller bypassing the router.
      If so, you can explicitly tell Devise which mapping to use:

      @request.env["devise.mapping"] = Devise.mappings[:user]

我甚至做得对吗?你应该对你的身份验证进行版本控制对于不同解决方案的建议非常受欢迎。

1 个答案:

答案 0 :(得分:1)

原来这一行

devise_for :users, :skip => [:sessions, :registrations, :passwords]

需要在命名空间块之外,如下所示:

   devise_for :users, :skip => [:sessions, :registrations, :passwords]
   constraints subdomain: 'api' do
    namespace :api, path: '/', defaults: { format: :json } do
      namespace :v1 do
        devise_scope :user do
          post 'login' => 'sessions#create', :as => :login
          delete 'logout' => 'sessions#destroy', :as => :logout
          post 'register' => 'registrations#create', :as => :register
          delete 'delete_account' => 'registrations#destroy', :as => :delete_account
        end

        resources :timelines do
          resources :entries
        end
    end
  end
end