[Rails]Session、Cookie和Flash

in ruby •  7 years ago  (edited)

在Rails中Cookies、Sessions還有Flashes是三種特殊的object,他們使用起來就像是hash一樣。

以下會介紹他們三個在Rails中的使用情境。

Session

在網頁中,由於HTTP是stateless的特性(也就是說server無法在不同的request/response cycle中記住資訊),所以每次request對server來說都是全新的request一樣,server無法得知上個request的狀態。

在實作上,我們會透過在每次client和server間的request加入一個特別的token(也就是session id),讓server知道這些request是來自於哪個使用者、又該紀錄怎樣的狀態。

所以實際上HTTP依舊是statelessness,但是我們透過傳遞session id,讓每次的請求都保持著連線。

舉例來說,當你登入FB後開始瀏覽動態,如果你想針對某個好友的動態點讚,如果沒有任何的東西幫你記憶你目前的狀態,Server會不知道這個request是哪個使用者送出(事實上是你)

在實務上session id常會被存在cookie當中,在每次的request/response中傳遞。

一般來說,每個送到server的request都會經歷以下的過程

  • Server檢查request中是否含有session id
  • 如果有session id,確認此session id是否有效
  • server叫出相對應的資料,並回傳給client端

在Rails中有四種機制來儲存session

  1. ActionDispatch::Session::CookieStore - Stores everything on the client.
  2. ActionDispatch::Session::CacheStore - Stores the data in the Rails cache.
  3. ActionDispatch::Session::ActiveRecordStore - Stores the data in a database using Active Record. (require activerecord-session_store gem).
  4. ActionDispatch::Session::MemCacheStore - Stores the data in a memcached cluster (this is a legacy implementation; consider using CacheStore instead).

Session除了幫助server記錄狀態外,也可以儲存少量的data。

在Rails中預設使用CookieStore這個選項來儲存session。這個選項最大的不同在於會將所有的session資訊存在cookie當中(經過加密),而不是單純透過存取session id,然後向server取得資料。Server可以直接透過cookie得到session德資料。

以下是在Rails常見的session用法

# Set a session value
session[:current_user_id] = user.id

# Access a session value
some_other_variable_value = session[:other_variable_key]

# Reset a session key
session[:key_to_be_reset] = nil

# Reset the entire session
reset_session

Cookie

我們可以把cookie想像成一個被存在client中的小資料庫,當client端送出請求到server時,會連帶的將這些資料一併傳到server端。而讓server跟client端保持連線的session id,也是被存在cookie中傳送到server端(與將資料存在client端的cookie相對應的,就是將資料存在server端的session)。

像是我們去購物網站購物時,即使我們沒有登入或著註冊該公司的會員身份,仍能夠將商品加入購物車當中。就是因為應用了cookie將資料儲存在瀏覽器上,所以在使用購物網站時,商品才能夠持續顯示在購物車中。

在上面的內容中我們有提到,Rails中是將session hash存在cookie裡。而由於session中常會有很多機密的資訊,所以Rails的使用了ActionDispatch::Cookies::ChainedCookieJars的module,讓cookie可以被加密,只有server才知道如何解開,避免在clinet端被讀取跟更改。

一般來說我們不會在cookie裡放入太多資料,因為cookie的儲存上限大約4kb。

以下是在Rails常見的cookie用法

# set a cookie value
cookies[:commenter_name] = @comment.author

# Delete cookie for the commenter's name cookie
cookies.delete(:commenter_name)

# Set cookie value with expiration dates
cookies[:name] = { value: "cookies YUM", expires: Time.now + 3600}.

Flash

Flash是session的一部分,而會在下次的request中出現並且被清掉,所以很適合用來顯示提示訊息。

如果你想要讓flash在當前的request就出現,你可以用 flash.now來達成這個目的。

def create
  @user = User.new
  if @user.save
    flash[:success] = "User was created"
    redirect_to user_path(@user)
  else
    flash.now[:error] = "Could not save user"
    render action: "new"
  end
end

參考資料:
Action Controller Overview
SESSIONS, COOKIES, AND AUTHENTICATION
Class ActionDispatch::Cookies < Object
Module ActionDispatch::Cookies::ChainedCookieJars
Web 技術中的 Session 是什麼?

Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!