關於session總結。
1.使用范圍
controller和view中可用
2.保存的數據
◇一般保存會話進行的必要數據,如保存登錄用戶的的ID:
user = User.find_by_name(params[:name])
session[:user_id] = user.id if user
◇盡量不要直接保存類實例到session里面。因為如果這個實例對應的表數據被更新,
而沒有同時更新session里保存的該實例,以后參照的session里的數據將成為舊的。
如:
⇒ user = User.find_by_name(params[:name]) #假設初值為 用戶名="xxx"
session[:current_user] = user if user #session[:current_user].name="xxx"
⇒ 處理過程中用戶修改了自己的name為"yyy" #用戶名="yyy"
而程序對session沒做任何處理
⇒ 之后參照session里的用戶名 #session[:current_user].name="xxx"
◇session保存形式
默認情況下rails程序的session數據保存在cookie中。
會話最早建立的時候WEB程序把cookie發給客戶端瀏覽器,
之后每次客戶端提交請求時瀏覽器都會把cookie的數據一起提交給服務器,用於驗證。
但是推薦把session數據保存到數據庫中,原因:
1.rails2.3.5中cookie中保存數據不能超過4k,否則會報異常。
2.大型系統的WEB服務器一般為了負載平衡會使用幾台服務器分擔處理。
這樣同一個會話的幾次請求可能會被分配到不同的服務器去。
為了使各服務器能共享session的數據,所以把session數據存到數據庫中比較妥當。
rails中把session數據保存到數據庫的方法:
1.建表
>rake db:sessions:create
>rake db:migrate
2.修改設置
修改文件environment.rb,如下:(默認第三行被注釋掉的,將注釋去掉)
# Use the database for sessions instead of the file system
# (create the session table with 'rake create_sessions_table')
config.action_controller.session_store = :active_record_store
※如果使用的rails版本是2.3以下,修改/controller/application.rb。(2.3以上無須修改)
如下,第三行中原有的#刪除。
# See ActionController::RequestForgeryProtection for details
# Uncomment the :secret if you're not using the cookie session store
protect_from_forgery :secret => '3f441a4b1dd0f7d17c7a15b8bb0b1482'
這樣WEB server(script/server)重新啟動后即可。
gitlab使用devise作為登錄框架,關於session的配置在config/initilizers/sessions.rb下,默認使用redis方式保存session
1
2
3
4
5
6
7
8
|
Gitlab::Application.config.session_store(
:redis_store, # Using the cookie_store would enable session replay attacks.
servers: Gitlab::Application.config.cache_store.last, # re-use the Redis config from the Rails cache store
key: '_gitlab_session',
secure: Gitlab.config.gitlab.https,
httponly: true,
path: (Rails.application.config.relative_url_root.nil?) ? '/' : Rails.application.config.relative_url_root
)
|
這里也可以改成在數據庫或者memcached里存儲,存儲格式與redis類似,不多講了。
redis里key為session id,value為序列化后的數據,默認使用的序列化算法為marshal,理論上只要php讀出內容來就可以取得session數據了。