I would like to request a Leaflet tilelayer without exposing my API key and secret. For example, using the UrtheCast API (but would apply to other similar APIs that embed api_key and api_secret in the URL), I am provided a map tiles URL like the following:


I can then load the tiles in Leaflet like:

var layer = L.tileLayer('https://tile-{s}.urthecast.com/v1/rgb/{z}/{x}/{y}?api_key=MY_API_KEY&api_secret=MY_API_SECRET&cloud_coverage_lte=20&acquired_gte=2016-02-26T08:00:00.000Z&acquired_lte=2016-04-27T06:59:59.999Z').addTo(map);

But, anyone looking at my JavaScript code would know my api key and secret.

The docs give the following warning: All apps developed are encouraged to be used internally or via a proxy. Otherwise there is a risk of exposing your API key and secret.

How can I make a proxy (preferably using PHP) to make a hidden call for Leaflet map tiles?


Basically you just need a PHP script that acts as a middle man and does the fetching for you, then returns what it gets directly to the client. I converted your JS snippet above into the relevant parts below.

Notice that the url in your Leaflet tileLayer example has been changed to a PHP endpoint with URL parameters: ?s={s}&z={z}&x={x}&y={y}

Next, the PHP script receives the URL parameters and concatenates them into a URL formatted for your urthecast.com assets.

Note that if your tiles are JPEGs, you'll need to change the Content-Type header in the PHP file.

Here's the relevant JS part:

var layer = L.tileLayer('http://yourdomain.com/get-tiles-proxy.php?s={s}&z={z}&x={x}&y={y}').addTo(map);

And here's the relevant PHP part:

    // get-tiles-proxy.php

    // Ingest the URL parameters
    $s = $_GET["s"];
    $z = $_GET["z"];
    $x = $_GET["x"];
    $y = $_GET["y"];

    header('Content-Type: image/png');

    // Concatenate the URL parameters into a properly-formatted url for your tile provider
    $path = 'https://tile-'.$s.'.urthecast.com/v1/rgb/'.$z.'/'.$x.'/'.$y.'?api_key=MY_API_KEY&api_secret=MY_API_SECRET&cloud_coverage_lte=20&acquired_gte=2016-02-26T08:00:00.000Z&acquired_lte=2016-04-27T06:59:59.999Z';

    // Then just return it..
    echo file_get_contents($path);

  • Thank you, works perfectly. Makes total sense now that I see it, although as someone with only the faintest grasp on PHP, I never would have got it on my own. Much appreciated. – phloem Apr 26 '16 at 22:11
  • No problem. It was a fun question to answer. :) – elrobis Apr 27 '16 at 19:05
  • sorry if I jump in after an year... I have a similar problem with tileLayer.wms, but this solution didn't work for me... See: gis.stackexchange.com/questions/258261/… – Fabio Marzocca Oct 12 '17 at 10:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.