Cookies in Real Life

One month ago, I’ve been diving into a Ruby on Rails project that presented some unique challenges, particularly around the different ways cookies can be utilized. Exploring this topic has been a valuable learning experience, especially when it comes to understanding how cookies are configured and behave in various scenarios. Since detailed resources on this subject seem to be limited, I’ve decided to compile my findings into a comprehensive guide. My goal is to create a resource that not only helps others but also serves as a handy reference for myself in the future. This tutorial is geared towards developers who are already familiar with creating controllers and actions in Rails. Let’s get started!

What are cookies?

Cookies are small text files that are saved in the browser and can be accessed from the Front-end or sent to the Back-end.

What are they used for?

Let me break it down for you in the simplest way: The HTTP protocol, which manages communication between the front-end and back-end, is stateless. This means it doesn’t retain any memory of previous interactions. For instance, when you're on a web page and click a link or button to send data to the back-end, the server treats your next action as an entirely new request, with no context of what happened before. Here’s an example to make it clearer:

Click on the steps:

1Front-end

You fill out the login form on your favorite Rails programming website.

2Front-end
3Front-end Back-end

Is it clear to you? If not, read it again because to understand what's coming next, the concept must be clear to you.

Setting up a cookie

Let's get into action. Open: app / controllers / application_controller.rb in your Ruby on Rails app and write the following:

Let's understand the code above: All you're doing is creating a callback so that the set_cookie method is called before any other action. Inside the method, we create the new cookie with the name "my_first_cookie" and then assign it a value of 'Learning cookies with Rails Genius'. That's it, your cookie is created. Now let's start our Rails server with the command rails server and visit the address localhost:3000 in our browser. We open the main page in our browser and we can see it in the apps tab of the developer tools (You can press f9 to open it)

Cookie Properties

my_cookie:

The name of your cookie. Name it as the name of the girl who rejected you for being a programmer 😅. A good practice is to use an intuitive name that starts with an underscore: _mysite_session

value:

It's the value you want to give to your cookie. Don't put complex things like active record models, it's better to keep the value as simple as possible. For example, if you want to store an active record model, just store its id and then look it up with that

domain:

The domain property tells us which domain or subdomain can access (read) the cookie. Let's look at some examples:

Our Domain will be: ruby_latam.com
The subdomain that created the cookie will be news.ruby_latam.com

Without setting the domain property

It will only send the cookie to the subdomain that created it and to no other.

  • news.ruby_latam.com WILL be able to read the cookie

  • jobs.ruby_latam.com WILL NOT be able to read the cookie.

domain: .ruby_latam.com

It will send to all subdomains.

  • news.ruby_latam.com WILL be able to read the cookie.

  • jobs.ruby_latam.com WILL be able to read the cookie.

domain: :all

It will send to all subdomains.

  • news.ruby_latam.com WILL be able to read the cookie.

  • jobs.ruby_latam.com WILL be able to read the cookie.

domain: %w(.ruby_latam.com .ruby_europe.org)

It will send to different domains.

  • news.ruby_latam.com WILL be able to read the cookie.

  • jobs.ruby_europe.org WILL be able to read the cookie.

secure:

If set to true, it means the cookie will only be transmitted from websites that have https. If you're testing on localhost, set it to false.

Tip: with the following command, it will be set to false if you're in development and true if you're in production:

http_only:

If this option is set to true, the Front-end will NOT be able to read the cookie; only the Back-end will be able to decrypt it.

expire_after:

The time after which the cookie expires once it has no activity. If you set it to one hour, with each new request it will be updated for another hour.

same_site:

none: Allows the cookie to be sent from any external site. This can lead to hacking through a Cross Site Request Forgery attack. I have a post where I explain how it works:

Understanding how CSRF works in Ruby on Rails

lax: This value is a good default option, as it allows cookies to be sent in most top-level navigation requests, but blocks them in cross-site contexts in certain cases, such as POST forms submitted from other sites. In other words, it will accept GET requests from other sites.

strict: In this case, the cookie will only be sent from the domain that created it. For example, if the cookie was created on blog.ruby_latam.com, the front-end must also be on blog.ruby_latam.com, otherwise it won't be sent. For example, if your front-end is on front_end.ruby_latam.com, the cookie will NOT be sent.

Becoming a Ruby on Rails Cookie Genius 🤯

Let's practice everything we already know: Create a new Rails app and then generate a controller in your terminal like this:

Open your new controller and in the set_cookies action we'll create our new cookie:

As you can see, the cookie is there and ready to be read. Now let's go to our next action and put the following:

Open the corresponding view at app/views/handle_cookies/set_cookie.html.erb and add the following:

You can see the result by navigating to the following URL:

Note that we set the expiration time to 5 minutes. If you take too long to complete the process, the cookie might expire. To regenerate it, simply visit the first action again. That's it 🎉🎉🎉🎉

Leaving Junior Level Behind 🏋️🥇

Now, let's explore some more advanced cases.

Signed Cookie

Suppose you want to send a cookie to the frontend so it can read the information, but you don't want a malicious actor to modify it. For this, there are `cookies.signed`. This will send the information to the frontend, but signed with a key that only the backend knows. If the information is altered at any point, the cookie will become invalid and return nil.

Creating:

Retrieving:

Encrypted Cookie

Similar to the signed cookie, this one will also be signed but with the additional difference that the data will be encrypted, so the frontend won't be able to read it.

Permanent Cookie

This cookie will be valid for 20 years. Use it if you want the data to be accessible for a long period of time

Tip: All these methods can be chained:

I hope you have managed to understand how cookies work. Don't forget that this is just the beginning and you should delve into other aspects later on your own.

Ruby on Rails is a wonderful framework that promotes rapid creation and its community firmly believes that there are ways to advance in technology without having to destroy each other. Best regards and see you next time.

Post a new comment. It's cool!

Developed in Bolivia 🇧🇴 by Marcelo Alarcón