我有一个内部带有API的Rails应用程序。我可以拨打电话,并使用access-token
中的gem devise_auth
进行身份验证。
我现在想为Web请求添加身份验证。我决定创建两个application_controllers
来处理两种类型的请求web
和api
。
两个控制器看起来像这样:
class ApplicationController < ActionController::Base
before_action :authenticate_user!
protect_from_forgery with: :exception
end
对于api
:
class ApiApplicationController < ActionController::Base
skip_before_action :verify_authenticity_token
include DeviseTokenAuth::Concerns::SetUserByToken
end
路线如下:
Rails.application.routes.draw do
devise_for :users, as: 'web'
mount_devise_token_auth_for 'User', at: 'auth'
root to: 'pages#home'
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
namespace :api, defaults: { format: :json } do
namespace :v1 do
resources :trainings, only: [ :index, :show, :create ]
post 'import', to: "trainings#import"
end
end
namespace :admin do
resources :trainings, only: [:index]
resources :users, only: [:index, :show]
end
end
我刚刚添加了web
前缀,以避免与相同的rails_path冲突。
我要访问的控制器是admin/users
,它继承自ApplicationController
:
class Admin::UsersController < ApplicationController
before_action :authenticate_user!
当我在浏览器中输入时:
http://localhost:3000/admin/users
我希望看到正常的设计行为,也就是看到网络上的登录表单。
不幸的是,该请求是由AuthTokenController接收的:
Started GET "/auth/sign_in" for ::1 at 2019-07-23 15:37:46 +0200
Processing by DeviseTokenAuth::SessionsController#new as HTML
Filter chain halted as :authenticate_user! rendered or redirected
Completed 401 Unauthorized in 1ms (Views: 0.3ms | ActiveRecord: 0.0ms)
我拆分了用于Web和api的控制器,以便可以使用protect_from_forgery
方法等。
但是我不知道如何在路由中告诉Rails,每当我执行Web请求时,它都会通过正确的控制器进行身份验证。
总而言之,我要点击以下网址:
http://localhost:3000/admin/users
与该控制器相对应的
admin_users GET /admin/users(.:format) admin/users#index
此控制器继承自
class Admin::UsersController < ApplicationController
before_action :authenticate_user!
此ApplicationController
使用:
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_action :authenticate_user!
end
在任何时候我都不会告诉该请求有关DeviseAuthToken
的任何信息。我不知道为什么要接受请求。
我的用户模型如下:
# frozen_string_literal: true
class User < ActiveRecord::Base
has_many :trainings
extend Devise::Models
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
include DeviseTokenAuth::Concerns::User
end
答案 0 :(得分:1)
从设计documentation:
对于Rails 5,请注意,protect_from_forgery不再位于before_action链的前面,因此,如果您在protect_from_forgery之前设置了authenticate_user,则您的请求将导致“无法验证CSRF令牌的真实性”。要解决此问题,请更改调用它们的顺序,或使用protect_from_forgery前置:true。