GithubHelp home page GithubHelp logo

vergilet / repost Goto Github PK

View Code? Open in Web Editor NEW
81.0 3.0 13.0 66 KB

Redirect using POST method

Home Page: https://vergilet.github.io/repost

License: MIT License

Ruby 98.85% Shell 1.15%
post redirect rails ruby sinatra repost redirect-post html-form

repost's Introduction

Gem Repost implements Redirect using POST method.

Implementation story and some details in the following article Redirect using POST in Rails.

Gem Version Build Status

Installation

Add this line to your application's Gemfile:

gem 'repost'

And then execute:

$ bundle

Or install it yourself as:

$ gem install repost

What problem does it solve?

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.

Usage

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:.

Example in Rails app:

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(...)

Example in Sinatra, Roda, etc. app:

class MyController < Sinatra::Base
  get '/' do
    Repost::Senpai.perform(...)
  end
end

Reminder:

  • 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

Full example:

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'
      }
    }
  }
)

Authenticity Token (Rails)

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})

License

The gem is available as open source under the terms of the MIT License.

Copyright © 2019 Yaro.

GitHub license

That's all folks.

repost's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

repost's Issues

Authenticity token?

Hi great and useful gem. Is there a way to set an authenticity token for a request? I assume this is a pretty common use case:

def redeem_via_code
  repost('/orders/rc',
    params: {
      code: params[:id]
    }
  )
end

Deprecation Warning in Rails 6

Thanks for making this super-handy gem!

Just a heads up that I'm seeing a deprecation warning after adding repost to a Rails 6 app. The warning shows up at the beginning of the rspec test suite. Here it is:

DEPRECATION WARNING: Initialization autoloaded the constants ActionText::ContentHelper and ActionText::TagHelper.

Being able to do this is deprecated. Autoloading during initialization is going
to be an error condition in future versions of Rails.

Reloading does not reboot the application, and therefore code executed during
initialization does not run again. So, if you reload ActionText::ContentHelper, for example,
the expected changes won't be reflected in that stale Module object.

These autoloaded constants have been unloaded.

Please, check the "Autoloading and Reloading Constants" guide for solutions.

It appears that the cause of this warning is line 2 in lib/repost/extend_controller.rb.

Roda support?

I tried it with Roda and it doesn't seem to work. Any idea if there will be support for Roda?

Not redirecting to specified url when in ajax request

Hi @vergilet,

I was checking this gem. My controller receives an ajax request, and after processing it, I need to redirect user to their specified url along with posting some payload.
I tried to use redirect_post method but it's not redirecting. Would it be possible to use while in ajax request?

Thanks

Error on older Rails installation

I'm on a EOL rails installation and returning this issue ( 4.2.6 , yes that old)

undefined local variable or method `content_security_policy_nonce' for for #

Ill have a pull-apart , might have to unbundle and comment out ?

ArgumentError: wrong number of arguments (given 2, expected 1)

Hello,
First off, thank you for a very nice gem!

We are running an older Ruby version; 2.3.8 in our production environment, and the gem breaks as the method String.concat does not allow for multiple arguments in 2.3.8.

In senpai.rb@24 the code states: form_head.concat(compiled_body, form_footer)

That results in an error: "ArgumentError: wrong number of arguments (given 2, expected 1)" in Ruby 2.3.8.

The gem works fine in my development environment as I use a higher Ruby version.

I think I'll be able to make a fix if wanted.

Kind regards
Mads

Error no template found while using Repost::Senpai to redirect API

Hi,

I'm trying to use this gems to redirect to other POST action in other controller API.
Repost::Senpai.perform('http://xxxx', params: { auth: request.params[:user] })
However I receive this error No template found for xxController#create, rendering head :no_content. I tried to add html.erb in views to solve that error. But after that, the response from my API is the HTML from the view. So it doesn't redirect to action in another controller, but only render the view.

Can anyone give me further explanation of how to use this gems to redirect controller API?
I have followed the documentation, but still can't redirect to the POST action

Thank you in advance

Partial string sent as param value when the params value has a quoted string in the value

Hi,
Thank you for the gem, we have recently encountered an issue and our tests were intermittently failing while using the gem for an use case when there is a quoted string in the param value the partial string is being sent
Screenshot 2022-07-19 at 21 24 53
I have tried to create pr to fix the issue but looks like i do not have permission
this is how i would go about fixing,
Screenshot 2022-07-19 at 21 26 34
Screenshot 2022-07-19 at 21 26 27
could you consider this changes and let me know your opinion

Getting undefined method error on Rails 6

It throws undefined method error on my Rails 6.

I am presently trying to use it for my Rails Api
Steps I took:

  1. add to gemfile:
    gem 'repost'
  2. Run bundle install
  3. Controller structure:
module Api::V1
  class UsersController < ApplicationController
    ...
   
       def create
      @user = User.new(user_create_params)
      if @user.save
        repost(api_v1_user_token_path, params: { auth: request.params[:user] })
      else
        json_response(@user.errors.full_messages, :bad_request)
      end
    end

  end
end

It however throws an error: NoMethodError (undefined method 'repost' for #<Api::V1::UsersController:0x0000558eeb152d98>)

Can't use ruby variables and routes into the params

Thanks for the great app. However, I cannot use instance variable into params.

          redirect_post(url,            # URL, looks understandable 
                params: {
                    'amt': amount,
                    'pdc': 0,
                    'psc': 0,
                    'txAmt': 0,
                    'tAmt': amount,
                    'pid': 'ee2c3ca1-696b-4cc5-a6be-2c40d929d453',
                    'scd': 'EPAYTEST',
                    'su': 'http://merchant.com.np/page/esewa_payment_success?q=su',
                    'fu': 'http://merchant.com.np/page/esewa_payment_failed?q=fu'
                },                                         # Your request body, also nested params and arrays       
                options: {
                  method: :post,                                   # OPTIONAL - DEFAULT is :post, but you can use others if needed
                  authenticity_token: 'auto'
                }
            )

I have a variable amount which return integer and the 'amt' parameter only accepts number. How do I solve this issue?

Nested posts ?

Im trying to recreate a post from shopify cart to test on

it has nested params,

Im returning - undefined method `map' for nil:NilClass Did you mean? Tap

Im assuming the repost map isn't set to handle nested values ?

RSpec Testing

Howdy! This is less of a bug and more of a question. I've been loving this gem as it solves some pains around a lot of the OAuth work I have been doing recently. Question is this: In system tests or controller RSpec tests...what is the best way to assert the behavior when the response is a redirect_post?

What I've done up until now is assert that the an instance of ApplicationController receives redirect_post with expected arguments, but it would be cool to assert that in a nicer way and even perhaps be able to stub that response so the controller still responds with a payload.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.