Rails 实现用户登录存取Session思路总结

《Ruby On Rails Tutorial 中文版》中的第八章,把思路总结了一下,大概是Session构建的9个过程:

第一步:新建controller

执行:rails generate controller Sessions,同时会创建一个Helper,之后我们会反复使用

第二步:定义路由

在routes.rb中追加:resources :sessions, only: [:new, :create, :destroy]

追加完毕之后,我们还需要写一下match:

match '/signin',  to: 'sessions#new', via: 'get'
match '/signout', to: 'sessions#destroy', via: 'delete'

第三步:写View层

因为程序中没有@session一类的实例变量,所以我们的form在使用时有一些区别: form_for(:session, url: sessions_path)

完成表单之后我们可以用params[:session][:symbol]来访问输入。

如果我们需要flash来显示我们的错误提示,需要使用flash.now: flash.now[:error] = 'Invalid email/password combination'

flash.now是专门在重新渲染页面时显示消息的,发出一个新的请求之后就会消失。

第四步:在application_controller中引用SessionHelper

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  include SessionsHelper
end

第五步:使用session[:remember_token]

session[:remember_token]记录用户状态,填入的内容可以用算法生成随机数,然后在数据库里新建remember_token列,保存加密后的结果。

rails generate migration add_remember_token_to_users

第六步:封装加密算法

在User model中加入:

def User.new_remember_token
  SecureRandom.urlsafe_base64
end
def User.encrypt(token)
  Digest::SHA1.hexdigest(token.to_s)
end
private
  def create_remember_token
    self.remember_token = User.encrypt(User.new_remember_token)
  end

需要指定的是remember_token前必须有self,否则的话会当成局部变量。

第七步:在helper中定义sign_in方法

前面我们说过,Session的Helper需要在之后用到,现在我们添加一个方法,之后可以在不同的地方重复使用这个方法了。

module SessionsHelper
  def sign_in(user)
    remember_token = User.new_remember_token
    cookies.permanent[:remember_token] = remember_token
    user.update_attribute(:remember_token, User.encrypt(remember_token))
    self.current_user = user
  end
end

这里我们使用了cookies.permanent,是Rails为了方便自定义的,定义失效时间为20年,否则的话就要通过:

cookies[:remember_token] = { value:   remember_token,
                             expires: 20.years.from_now.utc }

这样来定义失效时间,太麻烦了。

我们将加密后的remember_token存入数据库,加密前的存在cookies,之后我们可以通过匹配来验证身份。

第八步:读取cookies[:remember_token],查询数据库确认current_user

Helper中添加current_user

  def current_user=(user)
    @current_user = user
  end
  def current_user
    remember_token = User.encrypt(cookies[:remember_token])
    self.current_user ||= User.find_by(remember_token: remember_token)
end

最后Helper中我们通过定义sign_in?方法作为是否登录的检验

def signed_in?
    !current_user.nil?
end

可以看出就是把上面的current_user赋值与否进行判断。

不过每个页面都要查询一次。

第九步:destroy session

接下来我们定义一个sign_out方法,这样也能在需要用到的地方愉快的调用它。

  def sign_out
    self.current_user = nil
    cookies.delete(:remember_token)
  end

结束

(。-_-。)特别烦,终于that's all了。实际上啊,有一个名叫session[:symbol]的东西,都不知道这一章拼死拼活为了谁……

植入部分

如果您觉得文章不错,可以通过赞助支持我。

如果您不希望打赏,也可以通过关闭广告屏蔽插件的形式帮助网站运作。

标签: 知识, 语法, Rails

添加新评论