一、简介
rails中的session默认存放在cookies中,会话建立时web程序会把session发送给客户端浏览器的cookies,之后每次客户端提交请求时浏览器都会把cookie的数据一起提交给服务器,用于验证服务器端保存的session。一般建议将session保存到数据库中,原因是:
- rails中cookie保存数据大小有限制,一般不能超过4k,否则可能出错。
- 大型的web服务器一般为了负载平衡会使用几台服务器分担访问压力。这样同一个会话可能会被分到不同服务器上,就有可能会出现session验证失败的情况。
二、将session保存到数据库
创建sessions数据表
rake db:sessions:create rake db:migrate
配置session_store 在config/initializers/session_store.rb中加上如下一行代码:
Rails.application.config.session_store :active_record_store
意思是要告诉rails使用ActiveRecord去管理session
Ruby on Rails提供的session存储方案:
PStore(文件存储,默认方式)
ActiveRecordStore(数据库)
DRbStore
FileStore
MemoryStore配置后面可添加{ :expire_after => 12.hours }指定session失效时间,value为时间对象,如Rails.application.config.session_store :active_record_store,{ :expire_after => 12.hours }
- 重启服务,配置就完成了,接下来就可以使用了
session保存数据
一般保存会话进行的必要数据,如保存登录用户的的ID:
赋值
user = User.find_by_name(params[:name])
session[:user_id] = user.id if user#保存session
读取
session[:person]
清除
session[:person] = nil
全部清除
reset_session
三、cookies
Cookies 的读写是通过 ActionController#cookies实现的,cookie是用来记录客户端状态的,它保存在客户端浏览器中,以下是cookies的一些操作方法:
- 设置简单的cookie,这个cookie当浏览器关闭即失效
cookies[:user_name] = "david"
- cookie的value必须是字符串,其他数据格式需要转换格式
cookies[:lat_lon] = JSON.generate([47.68, -122.37])
- 为cookie签署rails程序的“secrets.secret_key_base“值,防止用户在浏览器中篡改
cookies.signed[:user_id] = current_user.id
- 为cookie签署rails程序的“secrets.secret_key_base“值,并可防止用户在浏览器中读取和篡改
cookies.encrypted[:discount] = 45
- 设置指定失效时间的cookie
cookies[:login] = { value: "XJ-122", expires: 1.hour.from_now }
- 设置”permanent” cookie,这个cookie失效时间为20年后
cookies.permanent[:login] = "XJ-122"
cookies.permanent.signed[:login] = "XJ-122"
- 读取cookie
cookies[:user_name] # => "david"
cookies.size # => 2
JSON.parse(cookies[:lat_lon]) # => [47.68, -122.37]
cookies.signed[:login] # => "XJ-122"
cookies.encrypted[:discount] # => 45
- 删除cookie
cookies.delete :user_name
#需要注意的是,如果cookie设置了域名,则删除时也要指定域名如:
#设置
cookies[:name] = {
value: 'a yummy cookie',
expires: 1.year.from_now,
domain: 'domain.com'
}
#删除
cookies.delete(:name, domain: 'domain.com')
- cookie的设置选项
:value - cookie的值
:path - cookie申请的路径,默认是程序的root路径
:domain - cookie所属的域名,默认为nil
:tld_length - 当domain设置为:all,这个参数可被使用,指定域名的长度,如:www.baidu.com,长度可设为1
:expires - 失效时间,值为time对象
:secure - 是否这个cookie只传送到HTTPS服务器。默认是false
:httponly - 这个cookie是否只用于HTTP。默认值为false。
四、补充
闪存哈希值。一个flash存储一个值(通常的文本)直到下一个请求。使用方法如下:
- 控制器中:
session[:user_id] = User.id
flash[:message] = "Data was saved successfully"
- 视图view中
<%= link_to "login", :action => 'login' unless session[:user_id] %>
<% if flash[:message] %>
<div><%= flash[:message] %></div>
<% end %>
关闭session会话管理(没有尝试过):
session :off # turn session management off
session :off, :only => :action # only for this :action
session :off, :except => :action # except for this action
session :only => :foo, # only for :foo when doing HTTPS
:session_secure => true
session :off, :only=>:foo,
:if => Proc.new { |req| req.parameters[:ws] } # off for foo,if uses as Web Service
如果flash的key是notice可在页面中直接用notice取值
一般说session失效,本质上是因为普通cookie失效,导致客户端提交的cookie记录的session id与服务器端的session匹配不上。