2

これが私のSessionsControllerです:

class SessionsController < Devise::SessionsController
  respond_to :json

  def create
    resource = warden.authenticate!(scope: resource_name, recall: "#{controller_path}#failure")
    sign_in(resource_name, resource)
    return render json: { success: true, path: root_path }
  end

  def failure
    return render json: { success: false, errors: ['Login information is incorrect, please try again'] }
  end
end

User#active_for_authentication

  def active_for_authentication?
    super && active_flag == 1 && has_active_subscription?
  end

サーバーの応答:

Started POST "/users/sign_in" for 127.0.0.1 at 2013-07-29 15:11:39 -0500
Processing by SessionsController#create as JSON
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"ozQ00tw9rRWExCmlIyIZR07ovnTLab5w0W44cLAKwA4=", "user"=>{"email"=>"dennis+dlksjfdkfjsd@recruittalk.com", "password"=>"[FILTERED]"}, "commit"=>"Sign In"}
  User Load (1.0ms)  SELECT "users".* FROM "users" WHERE "users"."type" IN ('User', 'Athlete', 'Coach') AND "users"."email" = 'dennis+dlksjfdkfjsd@recruittalk.com' LIMIT 1
   (0.6ms)  BEGIN
  AccountType Load (0.5ms)  SELECT "account_types".* FROM "account_types" WHERE "account_types"."id" = $1 LIMIT 1  [["id", 3]]
  AccountType Load (0.7ms)  SELECT "account_types".* FROM "account_types" WHERE "account_types"."id" = 3 LIMIT 1
   (0.5ms)  COMMIT
Completed 401 Unauthorized in 338ms


Started GET "/users/sign_in.json" for 127.0.0.1 at 2013-07-29 15:11:40 -0500
Processing by SessionsController#new as JSON
Completed 200 OK in 13ms (Views: 1.6ms | ActiveRecord: 0.0ms)

何らかの理由で、ブラウザーの要求に、電子メールとパスワードをプロパティとして持つユーザー オブジェクトが含まれています。エラー json は何らかの理由でレンダリングされません。何が間違っているのかわからない

編集

#Devise    
config.http_authenticatable_on_xhr = false

コーヒースクリプト:

  $(document).on 'ajax:success', '.user_modal_form', (e, data) ->
      context = $(this)
      if data.success
        $('input[type="submit"]', context).hide()
        $('.spinner', context).show()

        if data.path?
          window.location.href = data.path
        else
          location.reload()
      else
        e.preventDefault()
        if data.errors?
          $('.error-messages', context).html(data.errors).parent().show()
        else
          $('button', context).show()
          $('.spinner', context).hide()
          $('.alert', context).show()

      false
4

3 に答える 3

4

これは、後でこれに出くわす可能性のある人のために、私が最終的に行ったことです...

#config/initializers/devise.rb:
config.http_authenticatable_on_xhr = true
config.navigational_formats = [:"*/*", "*/*", :html, :json]

セッションコントローラー

class SessionsController < Devise::SessionsController
  respond_to :json

  def create
    resource = warden.authenticate!(scope: resource_name, recall: "#{controller_path}#failure")
    sign_in(resource_name, resource)
    return render json: { success: true, path: root_path }
  end

  def failure
    return render json: { success: false, errors: ['Login information is incorrect, please try again'] }
  end
end

ルート

# I have implemented STI (Single Table Inheritance) into my app, therefore I skip sessions and passwords for the :user scope    
devise_for :users, skip: :registrations, controllers: { sessions: "sessions", passwords: "passwords" }

ユーザーモデル

  def active_for_authentication?
    super && active_flag == 1 && has_active_subscription?
  end

  def inactive_message
    "Your subscription has been canceled or has expired."
  end

コーヒースクリプト:

  $(document).on 'ajax:success', '.user_modal_form', (e, data) ->
      context = $(this)
      log data
      if data.success
        $('input[type="submit"]', context).hide()
        $('.spinner', context).show()

        if data.path?
          window.location.href = data.path
        else
          location.reload()
      else
        e.preventDefault()
        if data.errors?
          $('.error-messages', context).html(data.errors).parent().show()
        else
          $('button', context).show()
          $('.spinner', context).hide()
          $('.alert', context).show()

      false
    .on 'ajax:error', '.user_modal_form', (event, xhr, ajaxOptions, thrownError) ->
      json = $.parseJSON(xhr.responseText)
      $('.error-messages', $(this)).html(json.error).parent().show()
于 2013-07-30T13:27:28.593 に答える
1

次のコードをセッション コントローラーに追加してfailure、コントローラーで JSON 応答をカスタマイズするメソッドを作成します。

def auth_options
  super.merge(recall: "#{controller_path}#failure")
end

def failure
  render json: {error: "Login failed"}, status: :unauthorized
end

どうやら のデフォルトのオプションはrecallです#{controller_path}#new。これをjsonリクエストのみに制限したい場合は、auth_optionsでrespond_toを使用できます。

于 2014-05-29T01:20:42.747 に答える
0

ログイン資格情報を含むオブジェクトを取得する理由はわかりませんが、Devise は FailureApp を介してエラーを処理します。401 がトリガーされたときに監視員がカスタム アクションをリコールするようにオーバーライドしてください。

これは、デバイスの初期化子で行われます。config/initializers/devise.rb

これを初期化子に追加して、サーバーを再起動します。

config.http_authenticatable_on_xhr = false
config.navigational_formats = [:html, :json]
于 2013-07-29T21:24:15.830 に答える