How to secure the JavaScript API Access Token?

2019-01-21 22:52发布

问题:

There are numerous online resources which provide JavaScript APIs to access their services. To be more clear, I will base my question on the example of MapBox, but this applies well to many other services in various domains.

When someone wants to use such a service in a web application (like the map imagery from MapBox for example), they typically need to Register/Sign Up and obtain an access token to access the service.

Now, if I would use the API from the server side - there is no issue: I know my token is stored securely somewhere on the server and is only "exposed" upon communication between my server and the service provider. However, in case of a JavaScript API (for example if I use Leaflet to render a map from MapBox), I am supposed to have my access token in a JavaScript which is exposed to the user's web browser - and so it makes it extremely easy to find someone's access token. In my example, simply going to any website using Leaflet and opening "Dev Tools" in Firefox reveals the token they use in a minute of attentive reading of their JavaScript code.

This token however, as for me, should be considered as a very secure data - service usage is tracked based on the authentication this token provides. If you pay for the service based on its usage it becomes very critical, but even if you don't (like, if you use a Free/Starter/Non Paid plan) - service usage is limited and I'd like to be sure it is only me who uses it.

Clearly, there are strategies like IP/domain filtering by service provider, for example, but it doesn't seem that all service providers support this - for example, MapBox doesn't seem to (or I didn't find it). Or, ultimately, I can proxy the service via my web server, but this is super heavy.

Given all that - is there a way to secure the access token used by a JavaScript API to access an external service, provided that JavaScript is executed in a user's browser?

回答1:

Restrict Access with CORS

Make your web server return the access tokens on an ajax request from you javascript with CORS setup. Token can be captured with this method visiting your app.

Provide Tokens to Authorized Users

You can also add authentication on your webserver to provide limited access to the users you allow. Token can be captured with this method but only by authorized users.

Proxy Requests

The only way to completely protect that token is to proxy the requests through your server. Token cannot be captured with this method.



回答2:

Javascript API tokens (and all client tokens, in fact) are always visible to the client (unless using them only server-side, as in node). There is no way around that. As you mentioned, the only way to truly secure an API key and keep it private is to store it in the server, then request the server to make the request on the client's behalf.



回答3:

I will speak only about map imagery APIs like Mapbox, it seems that unfortunatly only services like Google Maps, Here Maps, Bing Maps etc offer ip/domain filtering by service provider or this type of security, all offers based on OSM i met don't propose it. As Justin Poehnelt said the only reliable way is to build a proxy, but it's usually forbidden. I find this in the ToU of Mapbox:

You may not redistribute Map Assets, including from a cache, by proxying, or by using a screenshot or other static image instead of accessing Map Assets through the Mapping APIs.



回答4:

You may like to read up on CORS headers These allow you restrict which domain can call a remote web service.