CORS and Proxy
After getting the API keys and fetching it like normal, I kept getting Error 401: The application calling the API has not been authenticated. I thought it was authenticated because I already have the key and I didn’t quite understand why. So here is my thought process of finding out the solution.
Error 401: The application calling the API has not been authenticated.
What is Error 401?
The React App server is trying to call the API from TransportNSW website but has been unauthenticated. Even though we’ve got the API key as an authentication, TransportNSW website is a protected resource and needs authorisation.
But isn’t authorisation and authentication the same thing? No.
Authentication is a process to verify you as a person. It is when an entity proves an identity. In other word, it proves that you are who you say you are.
Authorisation is when an entity proves a right to access (or a right to request for API data in this case).
API key is a method of authentication, not authorisation. Anyone (especially any network) can pick up my API key and access the data so if the entire network becomes insecure, the entire network is exposed. So TransportNSW network has another facade to prevent leaked data to bad network. Thus, another step of authentication is needed to have the right to access the data.
Why is it not authorising?
Create-react-app runs on localhost:3000 by default- this is not a browser, it is a server. My web app is calling the API that is running on a different host which causes COR error (Cross-origin resource sharing).
COR allows a web page that has restricted resources (like TransportNSW) to be requested from another domain outside the TransportNSW server.
eg. Localhost:3000 is trying to sent request to another origin https://api.opendata
It is not authorising because my web app is trying to consume API running on different host and port.
Solution- Configure Proxys
Since the web application has to interact with multiple API servers which are hosted at different domains (stop_finder and departure_mon), we can configure proxy to avoid CORS errors.
What is proxy and why?
Proxy is a server that allows the clients (React.js) to seek for resources from other servers (TransportNSW API). This is due to TransportNSW has restricted request that are not from the same origin (our web application) to prevent attackers from injecting code like ads or plugins to steal our sensitive information.
How to set up a proxy?
- create setupProxy.js file in the src folder
- install npm package
npm install http-proxy-middleware
- in the setupProxy.js file, create a proxy constant and API Key constant
const API_KEY = '1234567890';const proxy = require("http-proxy-middleware");
4. Write a function to use this proxy and to make API call which forward to the URL
Because the default API proxy with create-react-app will not forward headers, we need to use headers: {Authorization: "apikey " + API_KEY}
which contains credentials to authenticate a user agent with a server.