Learn How To Use Ngrok with Applications Like Locally Hosted Nodejs Apps and Spring-Boot Based Apps In This In-Depth Tutorial:
In this tutorial, we will see a few sample applications using Ngrok. We will get to know more about integrating ngrok tunnels with Spring boot and nodejs based locally hosted application.
Other helpful ngrok features like ngrok inspect dashboard for the status of tunnels and capture traffic to the tunnel, making tunnels secure with http basic auth and making ngrok more configurable with the help of yaml based ngrok configuration file are also explained here in detail.
=> Check ALL Ngrok Tutorials Here
Table of Contents:
Create Sample Apps Using Ngrok
In this section, we will learn to create sample Spring boot and nodejs based locally hosted apps and try integrating them with the ngrok tunnels.
Spring Boot Application
Let’s get started with integrating ngrok with a simple spring boot web application. We will create a web application using Spring boot initializer and add a controller class for mapping the incoming requests.
Click here for the steps to create a web application using the Spring initializer.
Please note that we are just creating a spring boot app for illustration purposes and that’s the reason we are not setting up any further configurations/controllers in this sample application.
Once the project is initialized, add the following code to a new controller class – say “HelloController.java”. We’ll create 2 request mappings i.e. one is default which will print “Hello World!” and another method takes the username as a query string and displays “Hello {username}” text on the screen.
Please add the following code to the controller class.
@RestController public class HelloController { @RequestMapping("/") public String index() { return "Hello world application!"; } @RequestMapping("/hello") public String index(String name) { return "Hello " + name + "!"; } }
Once the above controller code is added, we need to build and run the application. The app should start on the localhost port 8080.
http://localhost:8080 – Displays “Hello world application!”.
http://localhost:8080/hello?name=User1 – Displays “Hello User1!”.
Now let’s host this application using the ngrok tunnel to get a web-accessible URL. To do that, simply go to the terminal and execute the below.
./ngrok http 8080
Once the above command is completed successfully, you can see the provisioned URL tunneling to the locally hosted spring-boot application.
Once the provisioned URL is available, it’s now time to try hitting our app from the web/Internet. Take the URL displayed after the tunnel is created (for ex. As in the screenshot above) and try hitting it from the browser (or curl on the command line).
Let’s try hitting the URL for our Spring boot controller requests.
Accessing the above-forwarded URL should print “Hello world application!” i.e. http://550e9d27.ngrok.io
Now let’s append our controller path to the URL and compare it with the localhost response.
http://550e9d27.ngrok.io/hello?name=user-from-web – Will display ‘Hello user-from-web’.
If you use the localhost instead of the above URL, then the response will still remain the same (which means that our local application is successfully tunneled now).
http://localhost:8080/hello?name=local-user will display ‘Hello local-user!’
NodeJS Application
Here, we will see ngrok integration with the node-based application.
In this section, we will get to know more about writing a nodejs based web server and then tunneling it through a publicly accessible URL which is exposed using ngrok.
Refer the sample code here to get started with the nodejs based web server.
Create a file named index.js in a fresh nodejs based project (or simply in any other folder on your system i.e. It can be done even using simple plain text files).
const http = require('http'); const hostname = '127.0.0.1'; const port = 3000; const server = http.createServer((req, res) => { res.statusCode = 200; res.setHeader('Content-Type', 'text/plain'); res.end('Hello World\n'); }); server.listen(port, hostname, () => { console.log(`Server running at http://${hostname}:${port}/`); });
After creating the above code file, navigate to the terminal/command prompt and run the command.
node index.js
Once this command is executed, a locally running node js based server should start. As we have mentioned the port no as 3000 in the index.js file that we have created, we’ll need to open the ngrok tunnel on this port.
First, try accessing the app on localhost:3000 and then start up the ngrok tunnel for this app using the command given below.
ngrok http 3000
Once successful, you can grab the URLs displayed/chosen by the ngrok server and then try accessing the exposed URL, to receive the same response as you would’ve got using the localhost:3000 url.
An important point to note here is, that when the ngrok hosted url is hit from that internet, you are not required to add port as a suffix after the URL’s in order to make it work, as you already mentioned the port when the tunnel got created.
Another important thing is, ngrok generally creates 2 urls i.e. one each for http and https based protocols.
Inspecting & Replaying Requests
In this section, we will see how to inspect what’s happening on the tunnel that we created. We’ll use the same node js sample application in the above example, and start the ngrok tunnel for the http port 3000.
Ngrok provides a web-based user interface to inspect the traffic coming to the webhooks created by ngrok as a result of the localhost tunnel being hosted. No matter what port you host the tunnel for, you would always be able to see the ngrok web-based UI at – http://127.0.0.1:4040 or http://localhost:4040.
Now, let’s see, how it looks like and what all can be done using this Web-based interface. The ngrok interface lists the URLs of the active tunnels as well as the detailed status in terms of connection duration, total requests, time taken to respond, etc.
Refer to the below 2 figures on tunnels:
Once the tunnel endpoint starts receiving the requests, all the traffic is captured in this UI. It simply acts as a proxy before the request actually hits the locally hosted application.
Let’s see how the traffic capture looks like:
With this captured traffic (as highlighted in the above figure), you might want to choose different things like:
- Repeat/replay a particular request of choice by clicking the Replay button.
- Clear all the captured traffic by clicking the Clear button.
- Search for a particular request or a group of requests using the web interface’s find text box at the top.
Note: With free accounts to ngrok, you can host a maximum of 1 tunnel at once. However, with paid accounts, you can host multiple tunnels and can see/inspect requests to all those tunnels through this web-based interface.
Integrating Authorization
There might be chances, that when you expose your locally running app to the web, you would not want anyone to access that without proper authentication/authorization.
With ngrok, you can specify a simple HTTP Basic auth while creating the ngrok tunnel, so that all the requests to the tunneled URL will need to contain/pass the requisite credentials in order to hit the locally hosted app. It’s as simple as accessing a document in a password protected way.
The command to password protect the tunnel is given below:
./ngrok http -auth "testUser:Pass12345" 3000
With this command, a tunnel to port 3000 will be started and it will be password protected with testUser as the username and Pass12345 as the password. The published tunnel url would not be accessible without the credentials and will throw HTTP403 unauthorized exception (HTTP 403) in case of missing/incorrect credentials.
When the traffic is inspected using the ngrok web-ui, we can clearly see that all the valid requests now contain the authorization header with HTTP basic as the authorization scheme.
Tunneling SSH Using Ngrok
Similar to http/https, we can also tunnel the local shell using ngrok. This simply means that we can expose the local terminal/shell to a remote publicly accessible url.
Although it does not solve a lot of use cases as we can expose files or any other content through the normal http, this is definitely an additional capability which ngrok provides.
The syntax for exposing the shell through ngrok is given below.
./ngrok tcp 22
Once the tunnel is established, you can simply ssh to the publicly created tunnel, using the below command.
ssh user@{tunnel-host} -p{portNumber}
Please note, that at times, the ssh remote connection is prohibited through the firewall and you might get a connection refused while trying to set it up remotely. In that case, work with the firewall setting and/or the hosts’ file setting to get it resolved.
Similar to the ssh port i.e tcp:22, you can also expose the other applications running on tcp ports like Postgres server on 5432. It really comes in handy when you are working as a team and you will have an option to expose your locally running setup to someone located remotely through a fairly easy setup.
Starting Tunnels Using Ngrok Config File
Here is a video tutorial:
Instead of mentioning the protocol and port address every time on the command line, you can also configure tunnels in the ngrok config file (which is a yaml based file).
Thus, if you have configuration needs and if the tunnel is frequently accessed, then it’s a good idea to use config file instead of manually creating/configuring the tunnel properties at every tunnel creation instance.
Moreover, you could configure multiple tunnels and choose to run some or all of them.
Let’s see some examples to understand it more clearly.
Command to be used for starting tunnel using ngrok config is:
./ngrok start {tunnelName}
First, let’s see, how does the ngrok config with tunnel configuration will look:
authtoken: {your-auth-token} tunnels: tunnel1: proto: http addr: 8080 tunnel2: proto: http addr: 3000
As you can see above, the ngrok config file contains authtoken and a list of tunnels as with configurations like protocol and port address.
Now you can specify one or more tunnels separated by spaces in order to start using the ngrok client. For Example, to start tunnel1 only from the config, you could simply execute:
./ngrok start tunnel1
For starting both the tunnels from the config file, use tunnel names separated by whitespaces.
./ngrok start tunnel1 tunnel2
For running all the tunnels present in the config file, use the above command with – all switch.
./ngrok start --all
Once the above command executes, you can see info that gets created around tunnels.
Please refer to the sample screenshot below:
Tunnel Status In Ngrok Dashboard
Here is a video tutorial:
We can see that all the tunnels that are started for the given user account on the web interface accessible at http://127.0.0.1:4040
You can also use the dashboard option to log in to the account and see the active tunnels in the dashboard.
Please refer to the screenshot below:
Conclusion
In this tutorial, we discussed more on integrating ngrok with applications like locally hosted nodejs apps/spring-boot apps, etc. In general, we can create publicly accessible secure tunnels for any local apps as well as applications hosted on TCP – like ssh or for that matter databases like Postgres.
We discussed utility tools like Web interface provided by ngrok to get real-time updates on who is hitting the secured endpoints.
Apart from that, we briefly touched upon integrating the authorization scheme with the published tunnel so that all the requests originating to that tunnel should provide proper credentials to access the resources.
Check out the upcoming tutorial to know more about Ngrok Alternatives in detail!!