What happens is that my homepage has a form to login users quickly, but since request_forgery_protection_token is nil when my app loads, protect_against_forgery? returns false and the form doesn't have a authenticity_token field.

So, when the user fill the form, it will be sent to UsersController#login, that will call protect_from_forgery that will finally set request_forgery_protection_token.

But since no token was sent, it will raise a InvalidAutenticityToken error.

To fix this, we just have to set on ActionController::Base:

@@request_forgery_protection_token = :authenticity_token

And while it's not released, I recommend to put the line above in your ApplicationController.

Your point of view is also interesting, but this is not what happens either.

When the request is sent to the UsersController, the request_forgery_protection_token is set, so the next attempts to login from the homepage WILL WORK, even with not requiring proctect_from_forgery in my controller.

The problem is that this is a very specific behaviour. Every time you start your server, only the first attemp to login from the homepage will fail, because in all other attempts, the authenticy_token will be correctly create since request_forgery_protection_token was set.

The actual implementation is just between what you said and what I'm saying.

I would recommend you to try this "bug" yourself. Try to "cross post" between your controllers using protect_from_forgery only in the receiver. The error will happen only on the first attempt.