这里的方法是将session存入数据库的方法
安装下面的gem
gem 'activerecord-session_store', github: 'rails/activerecord-session_store'
生产迁徙rails generate active_record:session_migration
然后在config/initializers/session_store.rb:中设置为数据库存储模式Foo::Application.config.session_store :active_record_store {:key => 'depot', :secret => '5xb5x1g92e965b95b16e49x79gxx9999', :expire_after => 1.years}
配置选项
key名称
secret安全码
expire_after过期时间
这里主要用来实现保存商品到购物车或者用户默认登录状态就是保持一年的
使用cookie保存session
在路由文件中添加session资源resources :sessions, only:[:new,:create,:destroy]
表单登录文件
<% provide(:title, "Sign in") %>
<h1>Sign in</h1>
<div class="row">
<div class="span6 offset3">
<%= form_for(:session, url: sessions_path) do |f| %>
<%= f.label :email %>
<%= f.text_field :email %>
<%= f.label :password %>
<%= f.password_field :password %>
<%= f.submit "Sign in", class: "btn btn-large btn-primary" %>
<% end %>
<p>New user? <%= link_to "Sign up now!", signup_path %></p>
</div>
</div>
表单post提交控制器 session的create方法
def create
user = User.find_by(email: params[:session][:email].downcase)
if user && user.authenticate(params[:session][:password])
sign_in user#用户登录成功就使用该方法记住该用户
else
# Create an error message and re-render the signin form.
end
end
由于我们需要长期记录用户登录状态,最安全的做法就是为每个用户生成一个安全标示符。具体的实现方法如下:
为用户表添加一个remember_token字段,该字段记录用户的登录情况。rails g migration add_remember_token_to_users remember_token:string
因为我们经常需要根据字段提取用户信息,所以我们也需要为该字段建立数据库索引
class AddRememberTokenToUsers < ActiveRecord::Migration
def change
add_column :users, :remember_token, :string
add_index :users, :remember_token
end
end
实现过程。首先我们先使用Ruby 标准库中 SecureRandom 模块提供的 urlsafe_base64方法生成一个长度为16的随即字符串,然后使用 SHA1 加密了记忆权标保存到数据库,用户登录时,查询用的remember_token是否和数据库中的一致,如果一致则判断为登录用户。
在User模型中添加创建remember_token的方法,在注册用户时,自动为每个用户添加一个remember_token。
class User < ActiveRecord::Base
before_save { self.email = email.downcase }
before_create :create_remember_token
.
.
.
def User.new_remember_token
SecureRandom.urlsafe_base64
end
def User.hash(token)
Digest::SHA1.hexdigest(token.to_s)
end
private
def create_remember_token
self.remember_token = User.hash(User.new_remember_token)
end
end
再来看看我们的登录方法:
module SessionsHelper
def sign_in(user)
remember_token = User.new_remember_token
cookies.permanent[:remember_token] = remember_token
user.update_attribute(:remember_token, User.hash(remember_token))#更新单个属性并保存到数据库
self.current_user= user#该方法是
end
end
其中permanent方法时下面的简写模式
cookies[:remember_token] = { value: remember_token,
expires: 20.years.from_now.utc }
我们来看看current_user= 方法的定义
def current_user=(user)
@current_user = user
end
如果我们想要获取当前登录的用户,可以使用下面的方法
def current_user
remember_token = User.hash(cookies[:remember_token])
@current_user ||= User.find_by(remember_token: remember_token)
end
当然我们需要定义一个常用的方法来判断用户是否登录
def signed_in?
!current_user.nil?#如果方法current_user为空,current_user.nil?为真,则signed_in?返回假,即用户没有登录
end