I am trying to create custom app out of OpenMRS and Bahmni. I have deployed all the services using docker, from this: GitHub - Bahmni/bahmni-docker: Configuration required to build and run bahmni docker images. I am using <base_URL>/openmrs/ws/rest/v1/session API for auth and it is working fine on postman, but when I try the same using webapp, it shows CORS issue on API call. Can help?
Can you put a screenshot of what the browser INSPECT window shows (in NETWORK tab). The details of the CORS error. Usually you would see a CORS error if the domain of the target API (openmrs), and the domain of the frontend are different. Also, for cross domain requests to be enabled, there needs to be some headers set (and server has to allow cross domain requests).
If you can provide more details, it will make it easier to answer. Bahmni frontend is making backend calls to openmrs and its working fine (no CORS error). So, is your custom app hosted differently?
I get following when I do inspect:
I am actually trying to develop a custom app out of OpenMRS APIs. I have hosted a Bahmni package using docker: GitHub - Bahmni/bahmni-docker: Configuration required to build and run bahmni docker images. And since it is on docker there are very few customization options on server side, apart from docker-compose.yml and .env. When I checked online and Bahmni wiki (https://bahmni.atlassian.net/wiki/spaces/BAH/pages/3117187073/OpenMRS+Configurations+docker) there are no information regarding CORS. How do I set headers on server side?
And yes, Bahmni frontend is working fine, it calls to openmrs backend, the custom app is under development and I am running just locally at the moment. I did call the required APIs using postman and there were no issues.
Hi @damadhav
A few points to note:
-
Postman, or curl, or other such tools used for making REST API calls do not perform Cross Origin checks. Only browsers perform them, to ensure that a person is not browsing a compromised (or malicious) website, that is making API calls behind the scene to a server which is from a different origin than where the frontend is hosted. For instance, you don’t want a bulletin board website making API calls to your already authenticated internet banking website behind the scenes. In your case, your app is running on an origin which is different from where Bahmni backend (OpenMRS) is running. Therefore, your browser is blocking this, to secure the user. In case of postman, you are only hitting a single origin, and hence you know where you are going. Therefore, postman doesn’t need to every perform Cross origin checks. The postman tool itself isn’t on a domain.
-
What qualifies as different origin? See this: Same-origin policy - Web security | MDN (Protocol, domain and port — all should match, to be in same origin).
-
CORS will allows different origin calls to be made. But that requires, backend to allow this frontend domain (or to allow ALL – * — which makes it insecure a bit). Better to have a whitelisted list of domains instead.
-
See this short EXCELLENT video to understand how CORS allows bypassing Single-Origin-Policy: What is CORS? | Cross-Origin Resource Sharing | CORS Explained! - YouTube
-
Now coming back to Bahmni. You either need to ensure your app runs in the same domain/network as Bahmni server, or you will need to make some changes in Proxy, to ensure CORS headers are attached in server API response, to allow your app. Something like this: How to Set Access-Control-Allow-Origin (CORS) Headers in Apache - Ubiq BI for Apache web server. Similar will be available for nginx, or other servers sitting in between your app & bahmni.
cc: @mohant @umairfayaz
thanks for the detailed explanation, but since I have deployed Bahmni docker version, can help regarding how do those changes you have mentioned on the dockerized version?
@gsluthra waiting on this one? can help please?
Hello @damadhav, For development setup until you get a base version of your extension app working, you can run chrome with CORS check disabled. You can read more about it here.
If you feel you don’t want to disable CORS check in browser and want to solve it by adding headers, you can do the change in proxy container. Below steps are for the same
- Exec into proxy container
docker compose exec -it proxy sh
- Edit the /usr/local/apache2/conf/bahmni-proxy.conf and add headers
Header set Access-Control-Allow-Origin "*"
- Save the file and exit.
- Restart proxy container by running
docker compose restart proxy
. Now you should not see CORS errors.
Note: You need to perform the above steps whenever you destroy the container and recreate.
Once you are done with devlopment, it is recommended to build your app as a docker container and add ProxyPass rules like this.
Let us know if you still face any issues.
Thanks
@mohant I did that and restarted container as well but the CORS issue still persists. Additionally, I did add further CORS configs on the same file but no reflection. I did add inside <VirtualHost *:443> section, any other section I should be adding in?
Can I do proxypass for development as well?@mohant update: I tried running the app in same server as well, but the CORS issue still persists. Is this because openmrs is running inside a separate container?
As debugged over call, the issue is due to the OPTIONS request made by browser for CORS check did not return a proper 200 response. This can be fixed by adding the following snippet along with the required CORS headers.
RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L]
Note: Please add only the required domains in headers to block unknown domains from making requests.
Great @mohant !! thanks!