Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between session[:food] and cookies.permanent[:food]

which are the difference between session[:food]="pizza" and cookies.permanent[:food]=pizza?
I tried to read rails documentation and it says:

Rails 2 introduced a new default session storage, CookieStore. CookieStore saves the session hash directly in a cookie on the client-side.

Then I don't understand, if session[:food] is saved in a cookie and so cookies.permanent[:food] does, what's the difference?

like image 718
zer0uno Avatar asked Nov 09 '13 15:11

zer0uno


2 Answers

if you do session[:food] you are using a traditional Rails session : this session object makes your value "pizza" available from page to page by storing it in a cookie that expires upon browser close ( which means if you close your browser, your session[:food] will be destroyed )

When we talk about permanent we talk about persistent sessions, so what means ?

persistent session is a permanent cookie that still exist ("forever") even if you close the browser, and don't expires only if you explicitly expire it or remove it .

but how to make a cookie that still exist "forever" ?

if i say "forever" it's because this is a tricky and the way to do this is to set a cookie expires for a long long time like 20 years from now or 60 years .... like this :

cookies[:remember token] = { value: "pizza", expires: 20.years.from now.utc }

This pattern of setting a cookie that expires 20 years in the future became so common that Rails added a special permanent method to implement it, so that we can simply write :

cookies.permanent[:food] = "pizza"

to answer your question, there is no difference in structure, each one is a cookie, but difference is only in the lifetime of each one

hope this help you

like image 82
medBouzid Avatar answered Oct 21 '22 15:10

medBouzid


I recommend you try it out, session data is base64 encoded in the cookie (rails 3) or in an encrypted cookie (rails 4) . Use a tool like Firefox 'Web Developer Extension' (WDE) addon, it has a cookie menu item, use it to delete all cookies for your localhost site, then add your code to a controller action

session[:food] = "pizza"
cookies.permanent[:food] = "pizza"

Now view the cookies using WDE

Name    food
Value   pizza
Host    localhost
Path    /
...

vs the session

Name    _session_name # (this value set in config/initializers/session_store.rb)
Value   a_base_64_value
Host    localhost
Path    /    
...

now open rails console and decode the session value

$ rails console
> Base64.decode64('value from session')
# works in rails 3

If using rails 4 the cookie is encrypted instead of just encoded, see http://cowbell-labs.com/2013-04-10-decrypt-rails-4-session.html

once decrypted or decoded it looks something like

{
  "session_id"=>"xxxxx", 
  "user_return_to"=>"/", 
  "flash"=>{
    "discard"=>[:alert], 
    "flashes"=>{
      :alert=>"You need to sign in or sign up before continuing."}
    }, 
  "food"=>"pizza", 
  "_csrf_token"=>"xxxxx"
}

Note in my case I am using Devise which has added a message to the flash

Session data is better protected and you also have the option to move to a different session store like a database without changing any code, just some configuration

like image 29
house9 Avatar answered Oct 21 '22 15:10

house9