How to make sure that only a specific domain can query from your REST api?

13,802

Simply define the header in your request, what this does is, it allows requests only from a certain domain, and instantly rejects any other domain.

response.set('Access-Control-Allow-Origin', 'domain.tld');

EDIT: IF you're really keen against web scraping stuff, you could make a function to double check client's origin.

function checkOrigin (origin) {
   if (origin === "your.domain.tld") {
     return true;
   } else {
     return false;
   }
}
/* Handling it in response */
if (checkOrigin(response.headers.origin)) {
  // Let client get the thing from API
} else {
  response.write("Send them error that they're not allowed to use the API");
  response.end();
}

Above example should work for the default HTTP/HTTPS module, and should also work for Express, if I'm not mistaken.

EDIT 2: To back my claim up that it should also work for Express, I found this quotation at their documentation;

The req (request) and res (response) are the exact same objects that Node provides, so you can invoke req.pipe(), req.on('data', callback), and anything else you would do without Express involved.

Share:
13,802

Related videos on Youtube

omega
Author by

omega

Updated on June 12, 2022

Comments

  • omega
    omega almost 2 years

    I have an app that has a REST api. I want it so that the only requests that can be made to the REST api are ones originating from the app itself. How can I do that? I am using a node.js+express server too.

    EDIT: the app is fully a public web app.

    • mrlew
      mrlew over 7 years
      Your app is a web app, right (not mobile)? Anyway, there's no way you can ensure 100% it (a user can easily simulate your requests outside your app). CORS protection is a technique to improve this kind of security inside the browser, but nothing prevents the user to user override the Origin header using a tool like curl, for instance. Indeed, CORS protection goal is more to protect the user, not the server. For API/resource protection, you should provide something like token authentication (oauth maybe), SSL.
    • omega
      omega over 7 years
      How does oauth work, couldn't someone just take the client key from the app, and make their own requests with that?
    • omega
      omega over 7 years
      I was thinking checking the ip and domain where the request came from, check if its the same domain where the app is hosted. Would that be enough?
    • mrlew
      mrlew over 7 years
      in Ajax requests, the ip will be the user IP. That's the problem.
  • omega
    omega over 7 years
    How does the client even get the api key, as the whole thing is a website. So the website is public.
  • omega
    omega over 7 years
    Web scraping techniques can get around this I think.
  • Cernodile
    Cernodile over 7 years
    You could just response.end() when responde.headers.origin isn't fit to your domain name, as secondary protection.
  • R. Gulbrandsen
    R. Gulbrandsen over 7 years
    It's quite normal approach to the problem. If you intend to use most of the public APIs then your client has to have an API key to access it. This is to restrict the number of requests as well as which applications that can access it. APIs like google maps, steam and flickr all uses it :)
  • omega
    omega over 7 years
    But then couldn't someone just take that public client api key and use it on their own requests?
  • Cernodile
    Cernodile over 7 years
    I have updated my post to show you how would you go around doing it.
  • omega
    omega over 7 years
    Is response.headers.origin the domain where the app is hosted and not the client user ip?
  • Cole Roberts
    Cole Roberts over 7 years
    @omega it's the domain where your app is hosted.
  • omega
    omega over 7 years
    Couldn't the user change the value of the domain with tools like curl, to be the same as where it really is hosted?
  • Cernodile
    Cernodile over 7 years
    You can't fully block those requests, if I remember correctly. So this would be your best bet for now.
  • omega
    omega over 7 years
    Is there a way to do this where the user doesn't have to login with username/password.
  • Cernodile
    Cernodile over 7 years
    Unless you make an authorization system, like make your users register first.
  • Cernodile
    Cernodile over 7 years
    However, you could make temporary API keys using features that actually NEED you to parse web content, and last until session is over.
  • ron
    ron over 5 years
    @omega could, but at that point you likely have rate monitoring or some stats to check. If you see suspicious activity, warn the user, rate limit, or revoke access using that key.