The ngrok tool comes very handy when you have to quickly expose your local Laravel environment to the outside world, by obtaining a disposable public URL that points to your local host machine. Although the process of getting the URL is trivial, there may be some tricky parts down the line.
Assuming your app is running at localhost:8080
, in your terminal execute ngrok http http://localhost:8080
.
Obtaining The Link
Resulting output should be quite similar to the following one:
ngrok (Ctrl+C to quit)
Help shape K8s Bindings https://ngrok.com/new-features-update?ref=k8s
Session Status online
Account Foo (Plan: Free)
Version 3.12.1
Region United States (us)
Web Interface http://127.0.0.1:4040
Forwarding https://12a3-45-678-910-11.ngrok-free.app -> http://localhost:8080
Connections ttl opn rt1 rt5 p50 p90
0 0 0.00 0.00 0.00 0.00
The URL is: https://12a3-45-678-910-11.ngrok-free.app
.
It will remain accessible until you quit the process. However, once you open this URL (notice the https
protocol), it may happen that your app is lacking any assets like styles and images. This may be due to the fact your Laravel app serves them through http
, not https
.
Middleware For The Rescue
Type php artisan make:middleware NgrokOverHttps
.
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\URL;
use Illuminate\Support\Str;
use Symfony\Component\HttpFoundation\Response;
class NgrokOverHttps
{
public function handle(Request $request, Closure $next): Response
{
if (Config::get('app.env') !== 'local') {
return $next($request);
}
if ($this->requestComesFromNgrok($request)) {
URL::forceScheme('https');
Config::set('debugbar.enabled', false);
}
return $next($request);
}
private function requestComesFromNgrok(Request $request): bool
{
return Str::endsWith($request->getHost(), 'ngrok-free.app');
}
}
Finally, let's attach it.
Open bootstrap/app.php
and append the newly created middleware class:
->withMiddleware(function (Middleware $middleware) {
$middleware->append(NgrokOverHttps::class);
})
Now, let's quickly break down the middleware's logic.
- The only purpose of it, is to expose local environment, any other case is not applicable, hence we skip the middleware.
- We define a narrative method that answers a human-intuitive boolean question.
- If the above condition is fulfilled, we force Laravel to serve everything using
https
scheme. - Debugbar is essential when developing, but its vast size gives me a feeling that it is better to disable it on fly.
- Finally we exit the middleware by proceeding to the next one.