2

I'm building an application and I'm having a hard time understanding how to properly restrict access to the API for its data while still allowing the sites and apps that run on that data to function.

The API is on its own domain (say api.mysite.com) and exposes several endpoints for getting data that will show on the site, and would be accessed via HTTP requests.

The public app is on a different domain (say myappsite.com) and needs to hit the api to get the data. My understanding is that I need to enable CORS on the api site, which I've done, so that it can serve the data to the site.

But even though CORS is enabled for only the public app site, I can still hit the api with POSTMAN and a raw HTTP client and see the data.

So my first question is: how does the webapi know that one is coming from the browser and the others are not? I tried copying the network request as cURL using the browser tools and importing that into Postman to try and replicate the browser request, but it still worked, even when I changed the origin to some random string. Why doesn't this get blocked?

But the more important question I have is, how do I prevent the API from being accessible from anything other than my site? I believe I could create a custom middleware that would check for certain headers, and maybe even a custom API key within, but since this would be sent publicly with the site requests, anybody inspecting the network traffic would be able to grab that key and make the requests...

Is the only way to do this by requiring the user to log in so the authorization filters available in webapi can block access? I know that would work, but I want the api data publicly available to my site, such that users do not have to create an account to see or use it...

but I also don't want some random other site using that same public api endpoints to scrape the data on my site and steal the content.

this question is further compounded by the fact that I'd eventually like to build a mobile app for this, and it would hit the exact same endpoints as the website, and it doesn't feel like there's a way to both make the data public but also protected...

Surely I'm not the only site that has public data that they don't want accessible by just anyone, how do other sites achieve this experience?

SelAromDotNet
  • 4,715
  • 5
  • 37
  • 59

1 Answers1

0

But even though CORS is enabled for only the public app site, I can still hit the api with POSTMAN and a raw HTTP client and see the data.

CORS is used to protect from requests coming from browsers. Postman and CURL are not browsers.

how do I prevent the API from being accessible from anything other than my site?

You API needs to have authorization enabled. For example, by means of JWT. This can be done in many ways, one of them is by using Auth0: https://auth0.com/docs/microsites/protect-api/protect-api. (Disclaimer, I work for Auth0).

Then, myappsite.com needs to have backend code (don't do this on the frontend!) that sets the authorization information prior to making requests to api.mysite.com.

Maria Ines Parnisari
  • 16,584
  • 9
  • 85
  • 130
  • thanks for taking the time to answer! I realize that postman and curl are not browsers, but my question is how does the API website itself know that they are not browsers? also, it sounds like you're saying that unless the api has authentication on it, there is absolutely no way to make it both public and protected? this sounds obvious, but also confusing as not every site has users create accounts to see their data, do they all just accept that anyone can steal their content so easily? – SelAromDotNet Jun 16 '22 at 19:34
  • @SelAromDotNet re: "how does the API website itself know that they are not browsers" see https://stackoverflow.com/a/58760390/1623249 – Maria Ines Parnisari Jun 21 '22 at 18:28