Module: Controllers::PostRedirectable
- Extended by:
- ActiveSupport::Concern
- Defined in:
- app/concerns/controllers/post_redirectable.rb
Overview
Renders a self-submitting HTML form that POSTs to a target URL. Replaces
the unmaintained repost gem (last released 2017) with a small inline
implementation.
Used for OmniAuth provider authorization endpoints that require POST
(with the CSRF token already in the URL via authenticity_token=).
Usage:
redirect_post(omniauth_authorize_path(...))
redirect_post(url, params: { foo: 'bar' })
The form auto-submits via JavaScript on load. A no-script fallback
("Continue" button) is rendered for clients without JS. CSP-friendly:
uses request.content_security_policy_nonce on the script tag when
CSP is configured (no-op when it isn't).
Instance Method Summary collapse
Instance Method Details
#redirect_post(url, params: {}) ⇒ Object
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'app/concerns/controllers/post_redirectable.rb', line 21 def redirect_post(url, params: {}) helpers = ActionController::Base.helpers nonce = request.content_security_policy_nonce fields = params.map { |k, v| helpers.tag.input(type: 'hidden', name: k.to_s, value: v.to_s) }.join.html_safe form_attrs = { id: 'post-redirect', method: 'post', action: url } script_attrs = { nonce: nonce }.compact body = helpers.safe_join([ '<!DOCTYPE html>'.html_safe, helpers.tag.html do helpers.safe_join([ helpers.tag.head { helpers.tag.title('Redirecting…') }, helpers.tag.body do helpers.safe_join([ helpers.tag.form(**form_attrs) do helpers.safe_join([ fields, helpers.tag.noscript { helpers.tag.('Continue', type: 'submit') } ]) end, helpers.tag.script( "document.getElementById('post-redirect').submit();".html_safe, **script_attrs ) ]) end ]) end ]) render html: body, content_type: 'text/html' end |