Search code examples
ruby-on-railsjsonrubyexternal-url

Passing sensitive and shorter data onto external links


I've recently wanted to start implementing APIs into my website but I've come across some problems regarding validations due to my lack of knowledge on how to properly send JSON data with Ruby on Rails. I've worked with some APIs and JSON in the past, but this is the first time I've done both at the same time, and my experience in RoR is still lacking.

My first instinct was to just concatenate the parameters onto the url and after seeing a more positive (albeit still incomplete) JSON response from the API, I thought I was on the right track, but after failing to get a successful response I started digging into what I was sending exactly, that's when I noticed two problems.

First problem was that there was sensitive information inside the URL like my clientID, information about a purchase like the price and description, along a secret key encrypted with MD5 and a bit of encryption salt, but according to the documentation it's safe and just for comparison with the server's received information, so all in all I was not too worried about compromising that kind of information. Still I wanted to improve on my code and protect as much information as possible.

My second problem was more significant, I noticed the information sent across was incomplete, due to the limited space in the url parameters.

Right then I knew I was doing something wrong, so I started digging for alternatives, preferably with a POST response, however I still lack the knowledge on how to properly send the parameters with a POST and the information was still when I tried using forms, worse still is that it seemed the parameters I was sending came out empty on the other end unlike my previous attempts, so I started to dig more into it.

Then I found that the link_to helper could send parameters, but after some testing it wasn't working and then I found out that to send parameters to external sites with rails, the suggested method was to concatenate the parameters into the url, so I came back full-circle.

So my question would be, how do you send parameters to an external website (preferably while keeping all the information as safe as possible) without a form (as all the information has previously been filled out in a previous form) in rails?

While I have worked with both APIs and JSON before, they are still subjects I'm not too comfortable working with them yet and to some extent I'm still learning a lot in RoR.

This was the code (the real one looks a bit different) that was giving me the most results:

My controller order_controller.rb

def confirm_order

  #Here I group all the parameters I'll need

  @payment_params = []
  description = "create_"+ @order.name.gsub(' ','_')
  device_info = "WEB"
  currency = @order.currency
  fee =  @order.price
  #this was to concatenate the url, previouly I had the name of each parameter and the "&" taken into account, the response was different as I added each.
  @payment_params << description << device_info << currency << fee
end

And in my view confirm_order.html.erb something like

<a href= <%="https://payexample/something/order?"+ @payment_params%> >Confirm order</a>

Any insight is welcome, but right now I'm really clueless on how to even approach the question as I've exhausted everything I've learned.


Solution

  • I’m a bit confused by what your UI looks like, but I would keep all of that info out of the link and make sure to do the confirmation in a POST (as some browsers preload links which can lead to unintended purchases if you keep it as a link). I would instead use the button_to helper.

    I’m not sure how you’re keeping track of the order, whether it’s in the database or session or what. So you may have to modify this a little to pass the right params through.

    https://apidock.com/rails/ActionView/Helpers/UrlHelper/button_to

    <%= button_to('Confirm order', action: 'confirm_order') %>
    

    Then in your confirm_order action, you can redirect to the payment site, as opposed to putting all of that confidential info on the page the whole time. If someone is watching the network traffic, they’ll see it come through in the header real quick, but it’s less easy to spot and a link on the page that you can open in a new tab multiple times.

    def confirm_order
      #Here I group all the parameters I'll need
    
      @payment_params = []
      description = "create_"+ @order.name.gsub(' ','_')
      device_info = "WEB"
      currency = @order.currency
      fee =  @order.price
      #this was to concatenate the url, previouly I had the name of each parameter and the "&" taken into account, the response was different as I added each.
      @payment_params << description << device_info << currency << fee
    
      redirect_to("https://payexample/something/order?#{@payment_params}")
    end
    

    I’m not exactly sure what you want that redirect url to be. That depends on the external site. If you need it to be querystring parameters, you can make a hash of keys and values and use the to_query method to turn it into a querystring.

    https://apidock.com/rails/Hash/to_query