2013-07-29 53 views
2

這裏是我的SessionsController:設計與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 

用戶#active_for_authentication

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

服務器響應:

Started POST "https://stackoverflow.com/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"=>"[email protected]", "password"=>"[FILTERED]"}, "commit"=>"Sign In"} 
    User Load (1.0ms) SELECT "users".* FROM "users" WHERE "users"."type" IN ('User', 'Athlete', 'Coach') AND "users"."email" = '[email protected]' 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 "https://stackoverflow.com/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 

的CoffeeScript:

$(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 

回答

0

我不知道爲什麼你得到了登錄憑據的對象,但設計處理錯誤通過它的FailureApp - 確保你覆蓋它,所以當401被觸發時,warden會回顧自定義操作。

這是在你的色器件初始化完成後,config/initializers/devise.rb

一下添加到初始化並重新啓動服務器:

config.http_authenticatable_on_xhr = false 
config.navigational_formats = [:html, :json] 
+0

調整我的代碼上面,以匹配我在我的應用程序中,我仍然得到同樣奇怪的問題的用戶對象被返回在JSON響應 – dennismonsewicz

4

這裏是我的傷口與去那些誰可能在稍後絆倒在路上...

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

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 

路線

# 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" } 

的usermodel

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

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

的CoffeeScript:

$(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() 
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,我認爲這可能對html有意義。如果您想限制爲只有json請求,則可以在auth_options中使用respond_to。