如何处理Ajax调用的身份验证失败?

时间:2019-10-20 19:30:21

标签: ruby-on-rails devise

我的rails控制器有两种类型的处理程序,一种是对网页的常规响应,另一种用于响应来自Angular的$ http get请求,并返回要由页面javascript代码处理的json。

我使用devise,并且此代码位于我的应用程序控制器顶部

 protect_from_forgery
 before_action :authenticate_user!
 after_action :set_csrf_cookie

问题是,例如,登录过时时,我认为authenticate_user正在将我的“未经授权”网页返回给调用者,而不是将通知调用者当前用户不再被授权的json,并且这样我就可以在客户端正确处理此情况。

任何关于有效方法的想法,都不必删除authenticate_user!来自应用程序控制器。

我的大多数控制器都具有约15条路由的处理程序,其中约50/50的处理程序旨在将json返回给ajax调用,而其他的则返回网页。我喜欢authenticate_user的安全性!在应用程序控制器中提供,并且不愿删除它,而不得不使用不同的代码来处理我的每个方法中的安全性。

谢谢。

1 个答案:

答案 0 :(得分:1)

要了解其工作原理,您必须真正了解Warden(该设计是建立在其之上)和Rack的。 before_action :authenticate_user!的作用是调用Warden.authenticate!并要求其标识用户。守望者通过使用策略识别用户。一种策略可能只是使用session[:user_id]从数据库中找到用户(在Devise中,这种情况发生在99%的时间),或者是诸如HTTP Basic Auth之类的更新颖的东西。

如果所有可用策略均失败,则调用失败应用程序。这是一个机架应用程序。在Devise this is just a basic Rails controller(Rails控制器是Rack兼容的应用程序)中,通常返回重定向。如果您在开发环境中运行Rails,尽管错误处理程序向您显示了友好的小异常页面,但您可能会收到HTML响应。

您可以通过提供自己的故障应用程序来自定义响应:

class CustomAuthFailure < Devise::FailureApp
  def respond
    self.status = 401 
    self.content_type = 'json'
    self.response_body = {"errors" => ["Invalid login credentials"]}.to_json
  end 
end
# config/initializers/devise.rb
config.warden do |manager|
  manager.failure_app = CustomAuthFailure
end 
相关问题