Ga Tech

1.01 everyday

Rails 4(5)

紀錄 Rails 3 to Rails 4 的一些改變。

FILTERS

在 Rails 3 當中常常使用的 before_filter,因為語意不清,因此在 Rails 4 改名為:before_action。(但是念舊的人依然可以在 Rails 4 當中使用 before_filter

SESSION

首先看一下 Rails 是如何儲存 session 的…

  1. browser 第一次發 request 給 server
  2. server 產生 session[:user_id] = user.id
  3. server 把 session data 傳送給 browser 並存成 cookie
  4. browser 之後發送的 request 當中就會夾帶 cookie
  5. server 接著拿來使用:@current_user ||= User.find(session[:user_id])

在 Rails 3 中,會先將 session 變數以 digitally signed cookies 的形式送給 browser,使用者無法針對此變數進行修改,但可以讀取。
Name: _AppExampleDigitallySigned
Value: BAh7CUk….
有心的使用者此時可以用 ruby code 將其解讀出來:

1
2
3
require 'rack'
cookie = "BAh7CUk..."
Rack::Session::Cookie::Base64::Marshal.new.decode(cookie)

就會得到 user_id 等有用的資訊:

=> {"session_id"=>"d3b170ba...", "user_id"=> "123", "csrf_token"=>"rtkofTr..."}

多少會有 security 風險存在。

因此在 Rails 4 當中又多做了一層 security:將其 encrypt。因此使用者既無法修改,也無法讀取。
Name: _ApplicationEnvryptedCookie
Value: REE3QXILc…

此時就算使用 ruby code 來解讀:

1
2
3
require 'rack'
cookie = "REE3QXILc..."
Rack::Session::Cookie::Base64::Marshal.new.decode(cookie)

就會得到 nil

SECURING SECRET KEY BASE

Rails 把 secret key base 放在下列位置,並以明碼顯示:

config/initializers/secret_token.rb
1
MyApp::Application.config.secret_key_base = '7014c47...'

因此如果要把 application 發佈為 public repo 的話,記得要改成環境變數:

config/initializers/secret_token.rb
1
MyApp::Application.config.secret_key_base = ENV['SECRET_KEY_BASE']

FLASH TYPES

在 Rails 3 當中,要使用 flash 的 helper methods 時,只能用 registered flash types:notice 以及 alert
在 Rails 4 終於能夠自訂了:

controllers/application_controller.rb
1
2
3
class ApplicationController < ActionController::Base
add_flash_types :grunt, :snarl
end

用法是:

controllers/users_controller.rb
1
2
3
4
flash[:grunt] = 'braaains...'
# 或是簡寫:
redirect_to @user, grunt: 'braaains...'

registered flash types:

views/users/show.html.erb
1
<div id="grunt"><%= grunt %></div>

Comments