为一个模型设计多条路径

nuT*_*707 2 ruby ruby-on-rails devise

我想有两条不同的设计路线:

  • 本地主机:3000/登录 - 标准设计身份验证
  • localhost:3000/api/login - 使用另一个非标准控制器/api/sessions_controller进行 api 调用的身份验证

路由文件

devise_for :users, path: '', path_names: { sign_in: 'login', sign_out: 'logout' }  
namespace :api, defaults: { format: :json } do
  devise_for :users,
             path: '',
             defaults: { format: :json },
             path_names: {
               sign_in: 'login',
               sign_out: 'logout',
              },
              controllers: { sessions: 'api/sessions' }
end
Run Code Online (Sandbox Code Playgroud)

铁路路线| 会话会话

new_user_session         GET     /login(.:format)  devise/sessions#new
user_session             POST    /login(.:format) devise/sessions#create
destroy_user_session     DELETE  /logout(.:format) devise/sessions#destroy
new_api_user_session     GET     /api/login(.:format) api/sessions#new {:format=>:json}
api_user_session         POST    /api/login(.:format) api/sessions#create {:format=>:json}
destroy_api_user_session DELETE  /api/logout(.:format) api/sessions#destroy {:format=>:json}
Run Code Online (Sandbox Code Playgroud)

api/sessions_controller.rb

class Api::SessionsController < Devise::SessionsController
skip_before_action :verify_authenticity_token
skip_before_action :authenticate_user!

respond_to :json

private

def respond_with(resource, _opts = {})
  render json: resource
end

def respond_to_on_destroy
  head :no_content
end
end
Run Code Online (Sandbox Code Playgroud)

该代码对我来说看起来不错,但是当我尝试使用身份验证凭据将 POST 请求发送到我的localhost:3000/api/login 时,它返回错误:

{"error":"您需要先登录或注册才能继续。"}

如果我注释掉我的默认设计路由并从 api 命名空间移动 api 路由一切正常,请求后返回我 json 和资源: routes.rb

#devise_for :users, path: '', path_names: { sign_in: 'login', sign_out: 'logout' }  
devise_for :users,
             path: 'api',
             defaults: { format: :json },
             path_names: {
               sign_in: 'login',
               sign_out: 'logout',
              },
              controllers: { sessions: 'api/sessions' }

namespace :api, defaults: { format: :json } do
  ...
end
Run Code Online (Sandbox Code Playgroud)

为什么会这样?我缺少什么?

Gui*_*rre 6

在我的路线中有这个:

Rails.application.routes.draw do
  devise_for :users,
    path: '',
    path_names: {
      sign_in: 'login',
      sign_out: 'logout'
    }

  namespace :api, defaults: { format: :json } do
    namespace :users do
      devise_scope :user do
        post 'login', to: 'sessions#create', defaults: { format: :json }
      end
    end
  end    
end
Run Code Online (Sandbox Code Playgroud)

rails routes 输出:

                                   Prefix Verb       URI Pattern                                              Controller#Action
                         new_user_session GET        /login(.:format)                                         devise/sessions#new
                             user_session POST       /login(.:format)                                         devise/sessions#create
                     destroy_user_session DELETE     /logout(.:format)                                        devise/sessions#destroy
                       api_v1_users_login POST       /api/v1/users/login(.:format)                            api/v1/users/sessions#create {:format=>:json}
Run Code Online (Sandbox Code Playgroud)

使 POST 请求http://localhost:3000/api/v1/users/login按预期工作 现在访问http://localhost:3000/login重定向到默认设备登录页面,并且登录正常工作。问题是你不能有相同的devise_for两次。在这种情况下,您可以拥有devise_for :usersanddevise_for :admin_users但不能两次相同:users