2

I want to give my clients access to my API. To make it convenient for customers to use my service, they just need to paste the javascript code into their html page.

But how do I differentiate access? I read about jwt, api keys, and tokens, but they should all be stored on the client side. This appears wrong.

What can I do in this situation? Customer convenience is very important, so I want to leave the possibility of simply inserting JavaScript code.

Maybe I can somehow track the domain from which the request goes or something like that?

P.S. I am using the Django Rest framework to build the API

kyle
  • 691
  • 1
  • 7
  • 17
AliMan
  • 21
  • 2
  • I don't see why pasting javascript is considered "Customer convenience" (imo you could just make him a webpage to serve the API). But, if you want to identify your client, through pasting javascript, your javascript needs to make an ajax call to your servers. And your servers need to authenticate the client (either a token generated before you send him the javascript, or for example, save the email of the client in the DB then ask for him to fill it in) – H. Figueiredo Feb 28 '19 at 11:46
  • The client on my site fills in all the necessary data. I can give him the API key. The essence of my service is that in each automatic mode, each time a visitor visits a client’s site, javascript code will be executed, which will send a request to my API and display the received data. The problem is that someone can open the developer tools in the browser, peek at the api key, and perform requests to my API under the guise of my client. I want to understand how I can protect myself from such) – AliMan Feb 28 '19 at 12:29
  • @AliMan — You can't. – Quentin Feb 28 '19 at 14:09

1 Answers1

0

From my understanding you want to protect your API key, but at the same time, the call to the API will be made from the client by some JS code you send him.

So how can you achieve this?

1. Scramble your js file - you can scramble your js file (jscrambler, obfuscator) so your code is irrecognizable. This however does not truly protect your js, if, by luck a client finds the scrambled variable corresponding to the API key, then they have access to it (though it's unlikely that happens).

2. Identify your client - The other option to do this is to identify your client and only allow identified clients to access your API (extra security on top of the API key). To achieve this you can:

  • Store your clients IP address - ask/collect your client's IP address on registry and store it in your DB. Then on the request, the IP address is collected and used to check if the client can access your API. However this process can fail if your clients don't have a static IP address.
  • Create a client fingerprint - Fingerprint2 with several elements of the client's machine (OS, screen resolution, IP address, browser, etc) you can create a "fingerprint" for each of your clients. It's not 100% reliable (pretty close though) and you would have to store it on the registry as well.
  • Create an API key for each client - You can also create an API key for each client and store it in the DB. This API key could be generated with the information of either of the 2 methods above (let's say for example you encrypt the IP address and that's your API key). Then, when JS code executed the call to your API, the IP address of the request would be encrypted and checked if it matched the API key.

All these methods are not 100% fail-proof, and you can find false-positives and false-negatives. But if you're supplying the client with the JS code, you're already limited in terms of security.

I hope this gives you some ideas of what you can do to protect your API.

Feel free to ask more if you have any other question or want more details about my suggestions!

H. Figueiredo
  • 888
  • 9
  • 18
  • 1
    "by luck a client finds the scrambled variable corresponding to the API key" — Who needs luck? They can just use the developer tools in the browser to inspect the outgoing HTTP request. – Quentin Feb 28 '19 at 13:57
  • "Identify your client - The other option to do this is to identify your client and only allow identified clients to access your API" — Here you use the term "client" to mean "browser", but the context of the question suggests it is actually "third party website visited by many different users" – Quentin Feb 28 '19 at 13:58
  • Yeah, your first point is true. If the client sees the HTTP request, it will find the API key anyway. – H. Figueiredo Feb 28 '19 at 14:08
  • Regarding the second point, I do understand what you mean. However, I do think if you get the IP address on the server side, you would get the "client's" network. As such, you could validate if the client (even though the visitors could come from a very different IP address). – H. Figueiredo Feb 28 '19 at 14:10
  • Since most websites provide services to "Anyone on the Internet", narrowing it down by network doesn't help. The Internet is a very big network. – Quentin Feb 28 '19 at 14:11
  • Yeah, but "anyone" would be the visitors. What I'm assuming is that, his API is serving "X" company, and "X" company is serving "Anyone on the Internet". If I have "X" company IP address, and check from which IP address the requests come (they come from "X" company because the visitor is using their website -> server). – H. Figueiredo Feb 28 '19 at 14:14
  • Maybe the request would actually come from the visitors and not "X" company, but I think if the IP address is collected on the server side (django framework in this case), you would get the IP address of the client="X" company. – H. Figueiredo Feb 28 '19 at 14:15