The documentation of ActionDispatch::Cookies
gives nearly identical descriptions for both signed cookies and encrypted cookies. It appears that both use secrets.secret_key_base
to prevent client-side tampering. http://api.rubyonrails.org/classes/ActionDispatch/Cookies.html
Sets a signed cookie, which prevents users from tampering with its value. The cookie is signed by your app's
secrets.secret_key_base
value. It can be read using the signed methodcookies.signed[:name]
cookies.signed[:user_id] = current_user.id
Sets an encrypted cookie value before sending it to the client which prevent users from reading and tampering with its value. The cookie is signed by your app's
secrets.secret_key_base
value. It can be read using the encrypted methodcookies.encrypted[:name]
cookies.encrypted[:discount] = 45
My question is: What is the difference between the two?
When would you want to use one over the other?
It's subtle, but the answer is in the documentation you provided. Signed cookies only guard against tampering, while encrypted cookies guard against reading and tampering.
More specifically, signed cookies call ActiveSupport::MessageVerifier
to append a digest (generated using secret_key_base
) to the cookie. If the value of the cookie is modified, the digest will no longer match, and without knowing the value of secret_key_base
, the cookie cannot be signed. The value of the cookie is merely base64 encoded, however, and can be read by anyone.
Encrypted cookies called ActiveSupport::MessageEncryptor
to actually encrypt the value of the cookie before generating the digest. Similar to signed cookies, if the value of cookie is modified the digest will no longer match, but additionally the value of the cookie cannot be decrypted without the secret_key_base
.
As to when you'd use encrypted versus signed cookies, it comes down to the sensitivity of the information you're storing in the cookie. If all you want to protect against is someone modifying the cookie, then sign it - but if you also need to keep the data secret, encrypt it.