Posts Tagged ‘lowpro’

AuthenticityToken and Javascript

Wednesday, August 6th, 2008

AuthenticityToken Javascript

The CSRF protection built into Rails 2 presented an issue when trying to make POST requests from anything other than a standard form. Rather than exclude numerous actions from protect_from_forgery, I made use of this snippet I noticed at http://madhatted.com (although slightly changed since ‘const’ isn’t support by IE):

<%= javascript_tag "var AUTH_TOKEN = #{form_authenticity_token.inspect};" if protect_against_forgery? -%>

While this is probably most useful for heavily Javascript/AJAX reliant applications, a simple use-case for this is creating a POST request from an anchor tag without using the messy ‘:method => :post’

In your RHTML:

<%= link_to 'Vote For This!', vote_for_article_path(@article), :class => 'method-post' -%>;

In your JS:

var anchorMethodPost = Behavior.create({
    onclick: function() {
        var f = document.createElement('form');
        f.style.display = 'none';
        this.element.parentNode.appendChild(f);
        f.method = 'POST';
        f.action = this.element.href;
        if(AUTH_TOKEN) {
            var s = document.createElement('input');
            s.setAttribute('type', 'hidden');
            s.setAttribute('name', 'authenticity_token');
            s.setAttribute('value', AUTH_TOKEN);
            f.appendChild(s);
        }
        f.submit();
        return false;
    }
});
Event.addBehavior({ 'a.method-post' : anchorMethodPost });

Note: the above example uses Dan Webb’s lowpro.

The code is shifted from the inline onclick attribute to your Javascript file; but now it’s reusable and cached. Pretty simple, but a lot cleaner.

If one was being genuinely unobtrusive; however, it would probably be best to start off with a full form and submit tag, and then switch that to an anchor tag through Javascript… if POSTable anchor tags are really that necessary that is…