为一个模型设计多种路径

时间:2018-11-27 06:03:02

标签: ruby-on-rails ruby devise

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

  • localhost:3000 / login-Standart devise auth
  • localhost:3000 / api / login-使用另一个而非标准控制器 / api / sessions_controller
  • 对api调用进行身份验证

routes.rb

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

铁路路线| grep sessio

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}

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

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

  

{“错误”:“您需要登录或注册才能继续。”}

如果我注释掉了我的默认设计路线并从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

为什么会这样?我想念的是什么?

3 个答案:

答案 0 :(得分:1)

在我的路线中有此提示

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

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}

http://localhost:3000/api/v1/users/login发出POST请求可以正常进行 现在访问http://localhost:3000/login会重定向到默认的devise登录页面,并且登录可以正常进行。问题是您不能两次拥有相同的devise_for。您可以同时使用devise_for :usersdevise_for :admin_users,但不能同时使用两次,在这种情况下,您可以同时使用:users

答案 1 :(得分:0)

我认为在初始路由定义中,您已经在API名称空间中,因此在定义控制器时,不需要

'api/sessions'

但是只是

'sessions'

我认为这将使请求命中正确的控制器,这意味着您的authenticate_admin!方法将不会触发(目前是这样),从而导致您的身份验证问题。

答案 2 :(得分:0)

我的答案:

routes.rb

devise_for :users, path: '', path_names: { sign_in: 'login', sign_out: 'logout' }
devise_scope :user do
   post 'api/login', to: 'api/sessions#create', as: 'api_login', defaults: {format: :json}
   get 'api/logout', to: 'api/sessions#destroy', as: 'api_logout', defaults: {format: :json}
end

与Guilermo Aguirre的回答很相似。