2012-04-03 34 views
1

它曾經是,在應用控制器這樣的線將完全禁用會話爲一個請求:如何爲Web爬蟲禁用Rails會話?

session :off, :if => Proc.new {|req| req.user_agent =~ BOT_REGEX} 

使用Rails 3.x中,這可能是不推薦使用或不再起作用。我意識到新概念是會話延遲加載,但即使它是一個web bot,通過應用程序的執行流程也會使用/檢查會話。

那麼是否有一些新的機制可以用來禁用每個請求的會話?

回答

1

似乎沒有成爲一個內置的方式在Rails 3中做到這一點,但你可以猴子補丁SessionHash得到了類似的結果:

class ActionDispatch::Session::AbstractStore::SessionHash 
    private 
    def load_for_write! 
     load! unless loaded? || (@env['HTTP_USER_AGENT'] =~ BOT_REGEX) 
    end 
end 

這將防止從會話存儲對象被創建。您仍然可以分配到session散列,甚至可以在同一請求中稍後訪問同一會話數據。

+0

咦 - 這真的很有趣。你怎麼會知道這事?也就是說,我怎麼能爲自己驗證這個?我猜想SessionHash.load_for_write的源代碼!方法? – Dogweather 2012-04-24 02:36:58

+1

您可以通過將用戶代理設置爲將作爲bot檢測到的內容(例如[in chrome](http://browserfame.com/314/change-user-agent-chrome-browser))來手動測試,刪除任何您可能擁有的現有會話Cookie以及瀏覽您的網站。每個操作Rails日誌都應該有「未找到會話」行 - 或者,如果使用ActiveRecord SessionStore,並且驗證沒有新的會話記錄被添加到數據庫中,您可以觀察會話表。 – jordoh 2012-04-24 19:13:56

+1

謝謝,但我想知道的是,你是怎麼想出這個解決方案的?你怎麼知道你可以做這樣的代碼替換?最後,放置代碼的最佳位置是在Rails啓動順序中工作的? – Dogweather 2012-04-26 08:36:07

1

我假設@ jordoh的答案適用於默認軌道cookie_store,但對我來說並不適用於使用active_record_store將我的會話存儲在數據庫中。

如果您正在使用active_record_store,並希望停止機器人正在創建的會話這個工程:

# Save this file as config/initializers/session_store_ext.rb 
# and don't forget to define BOT_REGEX 

class ActiveRecord::SessionStore 
    _set_session = instance_method :set_session 

    define_method :set_session do | env, sid, session_data, options | 
    unless env['HTTP_USER_AGENT'] =~ BOT_REGEX 
     _set_session.bind(self).call env, sid, session_data, options 
    end 

    sid 
    end 

    private :set_session 
end 

我已經寫了一篇博客文章,詳細說明這一點 - Conditionally Disabling Database Sessions in Ruby on Rails 3