2011-02-17 7 views
4

Je suis en train de faire un middleware qui change le paramètre authenticity_token avant qu'il ne parvienne à Rails.Rack et rack.request.form_vars/rack.request.form_hash

Je peux voir que env.inspect donne à la fois rack.request.form_vars et rack.request.form_hash. Les deux contiennent le jeton d'authenticité. Lequel utilise Rails et pourquoi Rack fournit-il les deux?

+0

J'aimerais aussi le savoir. Faites-moi savoir si vous trouvez quelque chose. – iain

+0

La recherche dans l'arborescence source de rails pour 'form_vars' et' form_hash' ne donne aucun résultat, suggérant que Rails n'utilise aucun des deux? Je suis aussi confus que toi. –

Répondre

7

Regardons la source! Les deux variables proviennent de l'utilisation de la classe d'assistance Rack::Request. Il fournit une belle interface aux paramètres de la requête. Il n'est pas nécessaire pour les applications Rack de l'utiliser, mais Rails l'utilise.

Les variables sont destinées à l'usage interne de Rack::Request. rack.request.form_vars contient le corps POST non analysé et rack.request.form_hash contient le hachage analysé. ActionDispatch::Request hérite de Rack::Request et obtient les paramètres en utilisant Rack::Request#POST, qui lit la dernière variable. Vous pouvez utiliser Rack::Request vous-même pour le modifier.

class YourMiddleware 
    def initialize(app) 
    @app = app 
    end 

    def call(env) 
    req = Rack::Request.new(env) 
    req.POST["authenticity_token"] = "foo" 
    end 
end 
+1

Regarder la source et comprendre la source sont deux choses différentes :) alors merci d'expliquer cela. – iain

3

Si vous avez une copie récente de rack qui comprend this pull request, vous pouvez utiliser Rack::Request#update_param:

request = Rack::Request.new(env) 
request.update_param :auth_token, 'XXXXXXXXXXXXXXXX' 

Tout comme la solution req.POST ci-dessus, cela va persister dans l'env qui est passé entre les intergiciels - mais c'est un appel de plus haut niveau destiné à faire face à des situations comme la vôtre.