ruby on rails中的session & cookies整理


一、简介

rails中的session默认存放在cookies中,会话建立时web程序会把session发送给客户端浏览器的cookies,之后每次客户端提交请求时浏览器都会把cookie的数据一起提交给服务器,用于验证服务器端保存的session。一般建议将session保存到数据库中,原因是:

  1. rails中cookie保存数据大小有限制,一般不能超过4k,否则可能出错。
  2. 大型的web服务器一般为了负载平衡会使用几台服务器分担访问压力。这样同一个会话可能会被分到不同服务器上,就有可能会出现session验证失败的情况。

二、将session保存到数据库

  1. 创建sessions数据表

    rake db:sessions:create
    rake db:migrate   
  2. 配置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 }

  3. 重启服务,配置就完成了,接下来就可以使用了
  4. 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匹配不上。

展开阅读全文

没有更多推荐了,返回首页