
What are persistent cookies? What are persistent cookies used for?
A persistent cookie is no different from other cookies. What is different is that it is used to identify users. With identification, it enables a website to remember you on subsequent visits, speeding up or enhancing your experience of services or functions offered. For example, a website may offer its contents in different languages. On your first visit, you may choose to have the content delivered in French and the site may record that preference in a persistent cookie set on your browser. When you revisit that site it will use the cookie to ensure that the content is delivered in French.
Why do I need it?
The biggest advantage is we can skip the registration step. We use persistent cookies to identify users. Users can be anonymous first time visitors or registered users. When we’re able to identify them(especially anonymous users), we can keep data like what items the user has placed on her cart. For e-commerce sites, you may not want to force the first time anonymous users to register when they try to place items in the cart. Some may be turned off and go away. By using persistent cookies to identify them, we can save which items they want without making them go through the registration process. You can make them register when its time to make payment.
How do I use them?
To use persistent cookies effectively, we’re segregating the web site into 3 levels of access.
- Public – anyone can go in. Examples would include your index page and FAQ
- Protected – cookie authenticated.
- Private – user must log in.
In your controllers, place a before_filter to identify which actions is private/protected
before_filter :cookie_required, :only => [:some_actions]
before_filter :login_required, :only => [:some_actions]
Use :cookie_required for protected actions, and :login_required for private areas.
How do I identify the users?
If you have seen through the code, there’re actually 3 models controlling the authentication system: identity, login_cookies and users.
- Identity – the unique identifier used to identify users. All users only have one identity, be it anonymous or registered users.
- Login_cookie – the cookies used for identifying the users.
- User – for identifying registered users.
One unique identity can have many Cookies, but only one User. So when you want to link to the user, use the Identity model instead. For example, you want to create a relationship where a user has many books:
class Identity < ActiveRecord::Base has_one :user has_many :login_cookies has_many :books end
Whenever your controllers need to link to the user, do it through the identity instead.
@identity.user
What if the user’s browser did not enable cookies?
Good question. If that happens, we will treat the protected region as private automatically. There’s no need for you to handle it. The code is created to degrade gracefully.
Implementation of persistent cookie authentication
The implementation is as suggested by Barry Jaspan and Charles Miller. In fact, Drupal‘s Persistent Login Module follows this set of implementation.
Special cases
There’s a special case you need to take note. For example, an anonymous user comes to your site, and place a few items on the cart. And then she registers as a new user. Will the data in her shopping cart be lost? The gem will ensure that her cookie entry and her newly registered user entry will be transferred to the same identity. But as I do not know how your website will be implemented, I did not implement the merging of the data from her cart. You’ll need to add your code to transfer the data to her new identity. An example of the implementation is here. You’ll need to modify the merge_identity function from user_controller.rb From app/controllers/user_controller.rb
def mergeIdentity(anonymousCookieValue, knownIdentityID) if anonymousCookieValue == nil || knownIdentityID == nil return false end return false if !LoginCookie.isAnonymous(anonymousCookieValue) loginValue = LoginCookie.getCookieLogin(anonymousCookieValue) #getting the both anonymous user's identity and the known identity anonymousCookie = LoginCookie.find(:first, :conditions => ["login = ?", loginValue]) anonymousIdentity = anonymousCookie.identity knownIdentity = Identity.find(knownIdentityID) return false if anonymousIdentity == nil || knownIdentity == nil #transferring the cookies anonymousIdentity.login_cookies.each { |cookie| cookie.identity_id = knownIdentity.id cookie.save } #transferring the cards anonymousIdentity.cards.each { |card| card.identity_id = knownIdentity.id card.save } #finally send the identity to its grave anonymousIdentity.destroy return true end
This is about all you will need to know to implement the persistent cookie authentication system effectively. Any bugs or unclear points, feel free to contact me.

Brilliant, was just sketching this out on a whiteboard a few hours ago.
Hello.
I’m trying to find a way of using per_auth_cookie. Seems a great plugin which fits my need. But.
How do I determine if a visitor is anonymous? isAnonymous is a class method which needs a cookie, there is no anonymus User and getCurrentUser raise an error when there is no user logged in.
Thanks for your answer. Regards.
Just perfect stuff
many thanks for that !
Wonderful, but usual =)