Rails 5设计:在sign_in失败时返回JSON

时间:2017-04-10 22:37:17

标签: ruby-on-rails json devise ruby-on-rails-5

我在这个问题上看到的所有内容都已过时和/或无效。

目标:当用户尝试通过移动应用程序中的JSON登录并且用户名或密码错误时,我希望Rails返回JSON数据,以便错误显示在应用程序上。

到目前为止,我已完成以下工作:

class Users::SessionsController < Devise::SessionsController
  # before_action :configure_sign_in_params, only: [:create]
  skip_before_action :verify_authenticity_token
  respond_to :json

  # POST /resource/sign_in
  def create
    self.resource = warden.authenticate!(auth_options)
    set_flash_message(:notice, :signed_in) if is_flashing_format?
    sign_in(resource_name, resource)
    yield resource if block_given?
    respond_with resource, :location => after_sign_in_path_for(resource) do |format|
      format.json {render :json => resource } # this code will get executed for json request
    end
  end
end

这在成功方面效果很好,但我不知道在失败时该怎么做。现在它返回一个未定义的方法错误:

undefined method `users_url' for #<Users::SessionsController:0x0000000195fa28>

2 个答案:

答案 0 :(得分:0)

你应该看看this SO question,它会指出你正确的方向。

基本上你需要处理登录失败。你可以这样做:

class CustomFailure < Devise::FailureApp
  def respond
    if http_auth?
      http_auth
    elsif request.content_type == "application/json"
      self.status = 401
      self.content_type = "application/json"
      self.response_body = {success: false, error: "Unauthorized"}.to_json
    else
      redirect
    end
  end
end

这会处理JSON请求。我希望这有帮助!

答案 1 :(得分:0)

想出来。无论我尝试了多少东西,CustomFailure似乎永远不会起作用。我能够通过handle_failed_login在

class Users::SessionsController < Devise::SessionsController
  # before_action :configure_sign_in_params, only: [:create]
  after_filter :handle_failed_login, :only => :new
  skip_before_action :verify_authenticity_token
  respond_to :json

  # POST /resource/sign_in
  def create
    self.resource = warden.authenticate!(auth_options)
    set_flash_message(:notice, :signed_in) if is_flashing_format?
    sign_in(resource_name, resource)
    yield resource if block_given?
    respond_with resource, :location => after_sign_in_path_for(resource) do |format|
      format.json {render :json => resource } # this code will get executed for json request
    end
  end

  private
  def handle_failed_login
    if failed_login?
      render json: { success: false, errors: ["Login Credentials Failed"] }, status: 401
    end
  end 

  def failed_login?
    (options = env["warden.options"]) && options[:action] == "unauthenticated"
  end 
end