Mutual TLS authentication and secure tunneling with ngrok

I am currently working on integrating a Payment Method with Shopify that requires me to validate their client requests using mTLS.

Payment apps must utilize mTLS for processing all requests where they act as the server and Shopify as the client. This is especially important when Shopify initiates sessions with payment apps. In such cases, Shopify uses its own client certificate, and payment apps must use the provided self-signed CA to validate that certificate. By implementing mTLS in these situations, payment apps can ensure that requests are initiated by Shopify and that the communication between Shopify and the payment app is secure.

In the past, I have used ngrok tunnels for various integrations with Shopify, but since they were not payment applications, mTLS was not required by Shopify, so I had no issues using the tunnels.

Now that I need to validate the client certificate on the server:

 https
  .createServer(
    {
      requestCert: true,
      rejectUnauthorized: true,
      ca: fs.readFileSync(path.join(__dirname, 'security', 'ca.pem')),
    },
    app
  )
  .listen(APP_PORT, () => console.log(`Server listening at: ${APP_URL}`));

'ca' in the code above refers to the certificate provided by Shopify in the documentation:

When trying to access my ngrok URL, I encounter the following message:

ngrok gateway error

The server returned an invalid or incomplete HTTP response.

ERR_NGROK_3004

After reviewing the ngrok documentation, I discovered that TLS tunnels can be used as well.

My initial question is: Will switching to a TLS tunnel prevent this error from occurring?

Furthermore, Shopify also requires:

The payment app must provide a certificate that Shopify will validate. This certificate should be a Trusted CA Signed SSL Certificate, not Shopify's self-signed CA.

My second question is: Will hosting the app on a server with an HTTPS certified URL fulfill this requirement? And is it acceptable to use a locally generated certificate while developing the app, for example with openSSL?

I seek your guidance as I do not have a paid ngrok account to access mTLS tunnels at this time.

Thank you for your assistance.


I am using Node + Express for the server.

Shopify Documentation:

Answer №1

I reached out to ngrok support with the following email:

Hello, my name is Juan and I require assistance with the integration of a Payment Method to Shopify that necessitates request validation using mTLS.

I have utilized ngrok tunnels in various other integrations with Shopify without any issues. However, now that I am implementing client certificate validation on the server, I am encountering an error when trying to access my ngrok URL: "ngrok gateway error - The server returned an invalid or incomplete HTTP response. ERR_NGROK_3004"

After reviewing the ngrok documentation, I learned about the option to utilize special TLS tunnels.

My query is: Will using a TLS tunnel resolve the error I am experiencing? I am considering upgrading my plan to access the TLS tunnel, but I want to confirm that it will fix the issue before proceeding.

Thank you for your assistance.

Ngrok support responded with the following:

Hi Juan,

We do offer mTLS support at our edge for HTTP tunnels. You can set up an endpoint configuration of the mutual TLS type and link it to your domain.

We also provide mTLS support at the agent or your server for our TLS tunnels, although this setup may be more complex.

If the solution does not work, we offer a 15-day money-back guarantee.

Best regards, Ben

Unfortunately, I was unable to upgrade my plan to access these features, so I proceeded to develop the app on a staging server where I encountered no issues. I hope this information proves to be helpful for you! :)

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Exploring the POST method functionality in AJAX

I am having trouble creating a function that uses AJAX. When I try to send information using the POST method, the function does not work, but it works fine with the GET method. Here is the function: function ajaxFunction(page,metho ...

Typescript's tree-pruning strategy design for optimization

I've been working on developing a library that enforces the use of specific strategies for each target. The current structure I have in place is as follows: [Application] -> contains -> [player] -> contains -> [renderer] In the current s ...

The body classList variable is inaccurately updated when making a JQuery Ajax call

Currently, I am in the process of developing a script to manage Ajax page transitions using JQuery's Ajax request function. Within the success callback of the Ajax function, it is essential for me to access the classList of the current page's bod ...

The issue arises when attempting to use input alongside debounce, event.persist(), and storing the value at the parent component

Is there a way to implement an input field with debounced search where the value is passed from the parent component? Currently, when I pass the value from the parent component it doesn't work as expected. What would be the correct approach to make th ...

PHP/AJAX user action history manager

Is there a library available that offers undo/redo functionality with a complete history for a web application? One possible solution could be a system using php/javascript/ajax where you can record the opposite action and variable state for each user acti ...

ajax always returns the same value, even when the input value is different

Each time I click on a different value, the console.log keeps giving me the same value. view image description I have checked the HTML code and found that even though each value attribute is different, it still returns the first value of the attribute. vi ...

Is there a way to automatically fill in a text field when an option is chosen from a dropdown menu populated with a list of objects?

When working with a DTO that has attributes id, name, and text, I am creating a list of these DTOs and passing them to my JSP using model.addAttribute. In the JSP, I am rendering a Spring list in the following way: <form:select path="notificationsId" i ...

The D3.js text element is failing to show the output of a function

I'm having an issue with my chart where the function is being displayed instead of the actual value. How can I make sure the return value of the function is displayed instead? The temperature values are showing up correctly. Additionally, the \n ...

What is the best way to format a time in a 12-hour clock using JavaScript?

Is it possible to create a timer that performs an action after 12 hours? I want the timer to start at 6am and end at 6pm, lasting for exactly 12 hours. Additionally, I'm interested in converting my current 12-hour clock into a 24-hour format. I am se ...

Receive the complete HTML page as a response using JavaScript

When making an Ajax post to a specific page, I either expect to receive an ID as a response if everything goes smoothly, or I might get a random html page with a HTTP 400 error code in case of issues. In the event of an error, my goal is to open the enti ...

Is it possible to test an Angular application using Protractor within an iframe that is hosted by a non-Angular

While trying to migrate a legacy app to Angular, we encountered an issue where the legacy app loads the new app in an iframe. Testing this integration with Protractor has proven challenging due to the fact that the legacy app is not built on Angular. If t ...

Issue with Bootstrap side navbar not collapsing when clicked on a link

Currently, I'm working on creating a website for a friend. While I used to have some experience with coding in the past, it has been a while and I am a bit rusty. This time around, I decided to use bootstrap for the project. However, I'm struggli ...

What strategies can be used to ensure that the page layout adjusts seamlessly to even the smallest shifts in window size?

Of course, I am familiar with media queries and how they allow us to set specific min-width and max-width ranges for CSS changes. However, when I look at the website styledotme.com, I notice that the block/div beneath the navigation bar gradually shrinks ...

Searching for items in a MongoDB collection using an array of values from a different collection

If I were to develop a sticker albums app where users can purchase albums and stickers, the relationship between users and albums would be many-to-many. Consider an example of my user collection: {"_id":{"$oid":"61a04f49909f8e972f5 ...

Disable checkboxes upon page initialization

I am working with a form that includes checkboxes. Whenever the page loads, clicking on the checkboxes automatically checks them. However, I am looking for a solution where the checkboxes are disabled or not clickable during the page load process. Once th ...

Can you explain the distinction between utilizing Object.create(BaseObject) and incorporating util.inherits(MyObject, BaseObject)?

Can you explain the difference between these two methods of setting the prototype? MyObject.prototype = Object.create(EventEmitter.prototype); MyObject.prototype = util.inherits(MyObject, EventEmitter); UPDATE I've noticed in various projects that ...

Having trouble with images not showing up on React applications built with webpack?

Hey there! I decided not to use the create react app command and instead built everything from scratch. Below is my webpack configuration: const path = require("path"); module.exports = { mode: "development", entry: "./index.js", output: { pa ...

Developing a timeline using a JSON file and dynamically altering the page based on the specified datetime within the JSON data

I am currently working on a project that involves a JSON file containing information about missions. This JSON file is subject to continuous updates and has a specific structure as shown below: [ { "module_id": 5, "title": "TITLE 1", "media ...

Retrieve the database value for the chosen name and then add that name to a different table

I am working on a dropdown feature that fetches categories from a database and displays the selected category price in a textfield. For example, when 'web development' is selected, the price ($12) will display in the textfield. Below is the cod ...

Elegant CSS background image fade effect

Having a small JS script that functions properly, but encountering an issue when quickly hovering over buttons causing the smooth transition effect to not work as desired. This abrupt change in image is quite unappealing. Any help would be greatly appreci ...