11 mars 2008

jquery et protect_from_forgery

protect_from_forgery est parfait pour protéger des attaques CSRF, mais il n'est pas possible d'utiliser les verbes POST, PUT, DELETE sans donner la clé au serveur.
Dans une implémentation rails classique c'est à dire avec prototype, c'est plutôt facile de faire des actions Ajax, car link_to_remote n'est autre qu'un formulaire avec la clé inclue.

Voici la solution que j'utilise avec jquery:
J'utilise des classes css sur mes liens pour dire quel verbe http utiliser. par exemple:
link_to 'toto', post_path(@post), :class => 'delete remote'

Mon code jquery pour géré le lien est les suivant:
$('a.remote.delete').bind('click',function(){
var _href = this.getAttribute('href')
$.ajax({
url: _href, data: {_method: "delete"},
beforeSend: function(xhr) {
xhr.setRequestHeader("Accept", "text/javascript")},
dataType: 'script',
type: 'DELETE'})
return false })


Jusqu'ici tout va bien... Malheureusement quand on essaie de cliquer sur le lien on aura une erreur, la clé n'est pas présente.
Donc je soumet la clé (form_authenticity_token) directement dans le lien. voici le petit helper qui m'aide à faire ça :
def secure_link_to(name, options = {}, html_options = nil, *parameters_for_method_reference)
options += (options.include?('?') ? '&' : '?') +
"#{request_forgery_protection_token.to_s}=#{form_authenticity_token}"
link_to(name, options, html_options)
end


Il suffit maintenant d'appeler:
secure_link_to 'toto', post_path(@post), :class => 'delete remote'
et le tour est joué.

Aucun commentaire: