I'm not sure if this is the appropriate place to post this, so if I need to move this to Stack Overflow please let me know.
I built a MERN stack app that calls the Mapbox API using the getmap method of the <ReactMapGL/> component. For now this means my Mapbox Token is exposed as it is sent as a part of the request endpoint. I would like to call the react map API from the back end... or find some way to hide my mapbox token.
I assume that because of the numerous renders and data formats like Tiles and Fonts, using my backend as a relay could potentially cause several issues and be an overall headache to manage.
Or, is there a need to hide the token at all, since I am only using the free tier of the API? I'm quite new to this so any help would be greatly appreciated.
Hi @hideodaikoku for security reasons, you should definitely store and call the Mapbox API from your backend. By exposing your secret token on the client side, it's possible for others to use your token to call Mapbox API and other services and you may have to pay for their usage if it's chargeable.
@bilafish this is what I thought but it raises two concerns:
Since it is a map based API and requires quick updates, will it affect the performance of the application?
How would you handle passing back the data and over-riding the getmap() method from the ReactMapGL component? Would I need to dig into the source code or create my own function that fetches the data, parses it and renders it at every component update?
Yeah, I'm super confused about this as well. None of the documentation on "securing" a token includes keeping it in the backend. As far as I can tell there's no reason you should ever be passing a token directly to the ReactMapGL component, you should be passing the map data after it's passed through your backend but I can't find anywhere that explains how to do that ....
I have no clue about how performance is affected by this solution, sorry 馃槙
I didn't actually implement this solution but I tried to think about this.
Let me know if any of this is wrong or if you did it successfully. 馃槃
You can probably get started with this post on StackOverflow.
Here is explained how to call an API from Backend and pass the data back to the Front.
Supposing your have your React Front served on the same server as your Backend, you could:
Client (React)
Provide mapboxApiUrl prop to the map component to override the default mapbox API URL.
(for this example : http:// localhost:
Client->Backend
Map component call backend API.
Backend -> Client
Backend call mapbox with token, get response, and send responseback to React-client.
Map should be rendered as it contains the same data from Mapbox API call.
@Siriusval that seems like the most straightforward way to go about things, but the issue is the app needs to keep updating in real time whenever the user moves the map around, zooms, etc. Sending the request from the back could result in a significant performance drop.
Also I am assuming this response data is not parsed as JSON and I can't seem to tell how it's implemented as everything is wrapped under the Mapbox MapGL component. I know for a fact that you receive tile data, images etc. but are these encoded in base64? do you get the raw image? 馃
In any case, thanks for taking the trouble to explain this so well! 馃槉 While I know quite well how front and back end services work I think it might be helpful for someone else visiting this issue to look at.
Yeah, right now, I've secured my tokens by returning them as part of the user's account information which works because my map pages happen to not be public and only visible after the user has signed in, however, this solution obviously wouldn't work if your map was on a public page.
Given the lack of documentation and how to flow all the tiles data through your backend, and the distinction between public and secret tokens, I'm leaning to believe that the public tokens don't need to be that secure because they won't incur that much cost? But if that's the case I don't know why the tutorials say to put them in a .env file ...
I'm guessing best practice for secret tokens is to keep them strictly in .env files that never leave your backend, but for public tokens it seems like best practice might be to not concern yourself too much with keeping them out of your front end and instead focus on URL restricting them so that they can only be used on your site?
You'd want to generate seperate ones for developing on localhost so that you can rotate / revoke those if they slip out since they can be used by any developer on their local machine, but as long as your production ones are url restricted to your domain/addresses they shouldn't pose too much of a risk if they're public?
In which case you could put them behind a public backend api call, but that's less about keeping it private since that's still scrapable and more about making it easier to rotate and change for each deployment environment.
Ultimately there is no way to hide a token in JavaScript. Mapbox supports restraining the request origin of a token. Similar approach is recommended by Google Maps to secure an API key.
See https://docs.mapbox.com/help/troubleshooting/how-to-use-mapbox-securely/#access-tokens
Most helpful comment
Yeah, I'm super confused about this as well. None of the documentation on "securing" a token includes keeping it in the backend. As far as I can tell there's no reason you should ever be passing a token directly to the ReactMapGL component, you should be passing the map data after it's passed through your backend but I can't find anywhere that explains how to do that ....