簡體   English   中英

skip_before_filter:authenticate_user! 不適用於AJAX呼叫

[英]skip_before_filter :authenticate_user! does not work for AJAX call

我有一個控制器:

class SessionTimeoutController < ApplicationController
  # snip

  skip_before_filter :authenticate_user!, only: [:has_user_timed_out]

  #snip

  # Determines whether the user has been logged out due to
  # inactivity or not.
  def has_user_timed_out
    @has_timed_out = (!user_signed_in?) or (current_user.timedout? (user_session["last_request_at"]))

    respond_to do |format|
      format.json { render json: @has_timed_out, status: :created}
    end
  end

  #snip
end

我使用AJAX向session_timeout/has_user_timed_out發送請求:

$.ajax({
  url: '/session_timeout/has_user_timed_out',
  type: 'GET',
  dataType: 'json',
  success: function( logged_out ) {
    if(logged_out === true)
    {
      window.location = '/users/sign_in?timedout=1'
    }
    else
    {
      checkTimeLeft();
    }
  }
});

進行此AJAX調用后,即使用戶注銷,我希望它始終會得到響應。 我期望如此,因為我設置了skip_before_filter :authenticate_user! 在控制器中。 但是,當我發送AJAX時,服務器會發回401 Unauthorized響應。 為什么是這樣?

此外,當我從瀏覽器控制台運行此JS時,它會按預期工作。 我的AJAX唯一的問題是從視圖中調用它時。

$.ajax({url: '/session_timeout/has_user_timed_out', type: 'GET', dataType:'JSON', success: function(logged_out) {console.log(logged_out + ' ' + typeof logged_out);}});

可能引起問題的一件事是,我在由於不活動而自動注銷的用戶瞬間就發送了AJAX請求。 這會完全混淆Devise嗎?


編輯:這是我發送導致401響應的請求時的Rails日志:

Started GET "/session_timeout/has_user_timed_out" for 10.0.2.2 at 2013-07-25 21:25:51 +0000
Processing by SessionTimeoutController#has_user_timed_out as JSON
  ConfigVar Load (0.2ms)  SELECT `config_vars`.* FROM `config_vars` WHERE `config_vars`.`name` = 'maintenance_mode' ORDER BY `config_vars`.`id` ASC LIMIT 1
  User Load (0.3ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 14 ORDER BY `users`.`id` ASC LIMIT 1
Completed 401 Unauthorized in 4ms

即使用戶已注銷,當我發送有效的請求時,這也是我的Rails日志:

Started GET "/session_timeout/has_user_timed_out" for 10.0.2.2 at 2013-07-25 21:29:39 +0000
Processing by SessionTimeoutController#has_user_timed_out as JSON
  ConfigVar Load (0.1ms)  SELECT `config_vars`.* FROM `config_vars` WHERE `config_vars`.`name` = 'maintenance_mode' ORDER BY `config_vars`.`id` ASC LIMIT 1
Completed 201 Created in 3ms (Views: 0.1ms | ActiveRecord: 0.1ms)

session_timeout/has_user_timed_out ,它看起來就像我在用戶session_timeout/has_user_timed_out后第一次向session_timeout/has_user_timed_out發送請求時,無論我等待多長時間,它都會失敗。 然后,所有后續請求成功。

我找到了解決方法。 $.ajax可以使用status選項,該選項使您可以根據服務器的響應代碼來攔截服務器響應。 就我而言,我關心的是用戶是否已登錄401錯誤告訴我用戶已注銷,因此我可以截取響應並采取相應的措施:

$.ajax({
  url: '/session_timeout/has_user_timed_out',
  type: 'GET',
  dataType: 'json',
  success: function( logged_out ) {
    if(logged_out === true)
    {
      window.location = '/users/timedout'
    }
    else
    {
      checkTimeLeft();
    }
  },
  // THIS IS THE CODE I ADDED FOR MY WORKAROUND:
  statusCode: {
    // If we get back an authentication error, it's a
    // pretty safe bet we're not logged in anymore
    401: function() {
      window.location = '/users/timedout'
    }
  }
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM