Rails 实现用户登录存取Session思路总结
《Ruby On Rails Tutorial 中文版》中的第八章,把思路总结了一下,大概是Session构建的9个过程:
第一步:新建controller
执行:rails generate controller Sessions
,同时会创建一个Helper,之后我们会反复使用
第二步:定义路由
在routes.rb中追加:resources :sessions, only: [:new, :create, :destroy]
追加完毕之后,我们还需要写一下match:
1match '/signin', to: 'sessions#new', via: 'get'
2match '/signout', to: 'sessions#destroy', via: 'delete'
3
第三步:写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
1class ApplicationController < ActionController::Base
2 protect_from_forgery with: :exception
3 include SessionsHelper
4end
5
第五步:使用session[:remember_token]
session[:remember_token]
记录用户状态,填入的内容可以用算法生成随机数,然后在数据库里新建remember_token
列,保存加密后的结果。
1rails generate migration add_remember_token_to_users
2
第六步:封装加密算法
在User model中加入:
1def User.new_remember_token
2 SecureRandom.urlsafe_base64
3end
4def User.encrypt(token)
5 Digest::SHA1.hexdigest(token.to_s)
6end
7private
8 def create_remember_token
9 self.remember_token = User.encrypt(User.new_remember_token)
10 end
11
需要指定的是remember_token前必须有self,否则的话会当成局部变量。
第七步:在helper中定义sign_in方法
前面我们说过,Session的Helper需要在之后用到,现在我们添加一个方法,之后可以在不同的地方重复使用这个方法了。
1module SessionsHelper
2 def sign_in(user)
3 remember_token = User.new_remember_token
4 cookies.permanent[:remember_token] = remember_token
5 user.update_attribute(:remember_token, User.encrypt(remember_token))
6 self.current_user = user
7 end
8end
9
这里我们使用了cookies.permanent,是Rails为了方便自定义的,定义失效时间为20年,否则的话就要通过:
1cookies[:remember_token] = { value: remember_token,
2 expires: 20.years.from_now.utc }
3
这样来定义失效时间,太麻烦了。
我们将加密后的remember_token存入数据库,加密前的存在cookies,之后我们可以通过匹配来验证身份。
第八步:读取cookies[:remember_token],查询数据库确认current_user
Helper中添加current_user
1 def current_user=(user)
2 @current_user = user
3 end
4 def current_user
5 remember_token = User.encrypt(cookies[:remember_token])
6 self.current_user ||= User.find_by(remember_token: remember_token)
7end
8
最后Helper中我们通过定义sign_in?方法作为是否登录的检验
1def signed_in?
2 !current_user.nil?
3end
4
可以看出就是把上面的current_user赋值与否进行判断。
不过每个页面都要查询一次。
第九步:destroy session
接下来我们定义一个sign_out方法,这样也能在需要用到的地方愉快的调用它。
1 def sign_out
2 self.current_user = nil
3 cookies.delete(:remember_token)
4 end
5
结束
(。-_-。)特别烦,终于that's all了。实际上啊,有一个名叫session[:symbol]的东西,都不知道这一章拼死拼活为了谁……
评论 (0)