Protect Your Google Maps API Key with Laravel Route Signature

I am building an App with Laravel & VueJs dealing with trips and using Google Maps to determine source and destination.
I need to send an email to the Client with trip details including the map.

Fortunately, Google provides a Service called Maps Static API which provides a way to path markers or polygons to the API and it returns an image with the map.

The problem is that I had to path the API key to the request query params, and this will make the key not secure and anyone can inspect and use it.

https://maps.googleapis.com/maps/api/staticmap?center=Berkeley,CA&zoom=14&size=400x400&key=YOUR_API_KEY

I had to figure some way to protect this secret key.
I had to make an API that receives the request from the client without exposing the secret key and call the google API through the server which appends the secret key internally without exposing the key to the public.

that sounds like making a public google API for free isn’t it?
so I had to figure some way to protect this API and make sure the server is only one that generates these images and no one can change the query params and uses my API for free.

Fortunately, Laravel provides a very easy solution for this (Signed URLs)
I sign the URL with a signature when sending it to the user via email and when the user calls this URL I can validate the signature and makes sure it is valid.

but how it works?
when using URL::signedRoute('unsubscribe', ['user' => 1]) as described in the documentation Laravel will use the route and its parameters and generate a hashed value with the app secret key which you generate when starting a new project and appends this hashed value in the request query params
?signature=878hkl.....&other_params=
when the user calls this signed URL the server accepts the URL and the query params without the signature key, then paths the remaining request to the hash function again, generates a new hash, and compares it with the one coming with the request to make sure that this route is valid.

Laravel provides a middleware which handles all this work for you.
All I need to do is to protect the route with this middleware
Route::get(‘map/static’, ‘MapController@staticMapImage’)->middleware(‘signed’)

after we solve the secret key protection challenge there is one more challenge remains.
Google API normally accepts query params with the same name, again and again, every time you want to draw a new point or path you have to construct the API like this
https://maps.googleapis.com/maps/api/staticmap?path=x1,y1|x2,y2&path=x3,y3|x4,y4....
so when using Laravel $request->query() to get the query params to pass it to google API later it only gets the last path because Laravel constructs an associative array from the query string which will normally miss the previous paths.
I’ll create another story soon describing how I make the use of Macros to overcome this problem.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store