Gem Repost implements Redirect using POST method.
Implementation story and some details in the following article Redirect using POST in Rails.
Add this line to your application’s Gemfile:
gem 'repost'
And then execute:
$ bundle
Or install it yourself as:
$ gem install repost
When you need to send some parameters to an endpoint which should redirect you after execution. There wouldn’t be a problem if an endpoint receives [GET], because you can just use:
redirect_to entity_url(id: @model.id, token: model.token...)
But when an endpoint receives [POST], you have to generate html form and submit it. So repost
gem helps to avoid creation of additional view with html form, just use redirect_post
method instead.
I faced with this problem when was dealing with bank transactions. You can see the approximate scheme:
P.S. The
repost
gem was initially created in response to the redirection process required by Adyen 3D Secure 1, which often involved creating an HTML form and submitting it via POST.
However, with the advent of 3D Secure 2, which aims for a more integrated authentication experience, the use of such forms for POST submissions has not been encountered. 3D Secure 2 typically manages authentication data exchanges in the background, potentially eliminating the need for manual form submission.
If you use Rails, gem automatically includes helper methods to your controllers:
repost(...)
and, as an alias
redirect_post(...)
Under the hood it calls render
method of current controller with html:
.
class MyController < ApplicationController
...
def index
repost(...)
end
...
# or
def show
redirect_post(...)
end
end
If you use Sinatra, Roda or etc., you need to require it first somewhere in you project:
require 'repost'
Then ask senpai to generate a string with html:
Repost::Senpai.perform(...)
class MyController < Sinatra::Base
get '/' do
Repost::Senpai.perform(...)
end
end
In Rails app use repost
or redirect_post
method in your controller which performs ‘redirect’ when it is called.
In Sinatra, Roda, etc. app or if you need html output - call Senpai
UPD: authenticity token is turned off by default. Use :auto
or 'auto'
to turn on default authenticity token from Rails. Any other string value would be treated as custom auth token value.
# plain ruby
# Repost::Senpai.perform('http://......)
# Rails
redirect_post('http://examp.io/endpoint', # URL, looks understandable
params: {
a: 1,
'b': { "c": 2 },
d: [ 3, 4, 5 ],
e: { f: 'string', g: [ 6, 7, 8 ] }
}, # Your request body, also nested params and arrays
options: {
method: :post, # OPTIONAL - DEFAULT is :post, but you can use others if needed
status: :ok, # OPTIONAL - DEFAULT is :ok. This is the http status that the form will be returned with.
authenticity_token: 'auto', # OPTIONAL - :auto or 'auto' for Rails form_authenticity_token, string - custom token
charset: 'Windows-1251', # OPTIONAL - DEFAULT is "UTF-8", corresponds for accept-charset
form_id: 'CustomFormID', # OPTIONAL - DEFAULT is autogenerated
autosubmit: false, # OPTIONAL - DEFAULT is true, if you want to get a confirmation for redirect
autosubmit_nonce: '1d3n7i4ier', # RAILS - DEFAULT is content_security_policy_nonce, for pure Ruby - string identifier, more info - https://edgeguides.rubyonrails.org/security.html#content-security-policy
decor: { # If autosubmit is turned off or Javascript is disabled on client
section: { # ... you can decorate confirmation section and button
classes: 'red-bg red-text', # OPTIONAL - <DIV> section, set classNames, separate with space
html: '<h1>Press this button, dude!</h1>' # OPTIONAL - Any html, which will appear before submit button
},
submit: {
classes: 'button-decorated round-border', # OPTIONAL - <Input> with type submit, set classNames, separate with space
text: 'c0n71nue ...' # OPTIONAL - DEFAULT is 'Continue'
}
}
}
)
Currently you can pass the authenticity token in two ways:
Recommended:
Use options
and :auto
to pass the auth token. That should protect you from any implementation changes in future Rails versions
redirect_post('https://exmaple.io/endpoint', options: {authenticity_token: :auto})
Or, it is still valid to:
use params
and form_authenticity_token
method directly from ActionController
redirect_post('https://exmaple.io/endpoint', params: {authenticity_token: form_authenticity_token})
The gem is available as open source under the terms of the MIT License.
Copyright © 2019 Yaro.
That’s all folks.