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]的东西,都不知道这一章拼死拼活为了谁……
植入部分
如果您觉得文章不错,可以通过赞助支持我。
如果您不希望打赏,也可以通过关闭广告屏蔽插件的形式帮助网站运作。