关于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数据了。