How to allow CORS in Google Cloud Endpoints? - google-app-engine

As stated in the January 2017 Endpoints release notes, I tried to update my openapi.yaml file to stop the Extensible Service Proxy (ESP) from blocking cross-origin requests by adding to x-google-endpoints:
swagger: "2.0"
info:
description: "Market scan using technical indicators."
title: "Talib Test"
version: "1.0.0"
host: "YOUR-PROJECT-ID.appspot.com"
x-google-endpoints:
- name: "YOUR-PROJECT-ID.appspot.com"
allowCors: "true"
basePath: "/"
consumes:
- "application/json"
produces:
- "application/json"
schemes:
- "http"
...
I continue to get an error in the browser when trying to make http calls from my angular application. The error is in both developer mode and after I deploy my angular application:
XMLHttpRequest cannot load
Response to preflight request doesn't pass access control check:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
When i look at Google Cloud logging I see that requestMethod:"OPTIONS" and status:200. The API is a POST method so I'm guessing it's the ESP blocking the request. Also, I have allowed CORS in my python application using FLASK-CORS so it should be working.
My application has two services that are both on Google App Engine. The first is Standard Envrionment. The second, which I am having issues with is Flexible Environment. I am using a dispatch.yaml file and separate openapi.yaml files if that's relevant. Also, the API works on hurl it and postman.
Any help would be awesome!

Most likely your backend application did not handle CORS OPTIONS correctly.
If "allowCors" is true, Endpoint proxy will pass the request to your backend application. Proxy will not add anything to the request. If "allowCors" is false, proxy will return 404.

Related

Enable CORS in an Angular Paypal Docker application

My application with angular front end and springboot backend is trying to make a REST POST call to one of the PayPal APIs from Angular front end. The application is deployed as a Docker container in GCP VM instance. If I dont open the broser with web security disabled I get the ERROR
"Access to XMLHttpRequest at 'https://pilot-payflowpro.paypal.com/' from origin 'http://myserverip' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource."
I see lot of answers for this question in SO and others with adding headers in httpd.conf / .htaccess files. But I dont have both these files. I tried adding headers to Dockerfile and also adding commands to docker-compose.yaml file. Also tried adding the end URL in angular proxy configuration file. None of it worked.
Is there any way to enable CORS either in a docker config file or in the server itself.
docker-compose.yml
image: docker.image.link
privileged: true
ports:
- '80:8080'
restart: 'no'
volumes:
- '/var/sftp/upload:/usr/share/invoice/invoiceFile'
environment:
- SPRING_PROFILES_ACTIVE=docker
- DB_CONN_STRING=jdbc:postgresql:url
- DB_USER=postgres
- DB_PASS=postgres
- HOST_NAME=hostname
- SMTP_HOST=smtphost
- SMTP_PORT=25
- SMTP_AUTH_TRUE_FALSE=false
Dockerfile
FROM openjdk:8-jdk-alpine
ARG JAR_FILE
ADD target/${JAR_FILE} /usr/share/application.jar
ADD template/ /usr/share/template
VOLUME /tmp
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/usr/share/application.jar"]
The CORS error is an error emitted by the browser when the request response, from the backend, hasn't the properly headers to tell to the browser that this client can perform/view the request.
So, in your case the backend is the PayPal (https://pilot-payflowpro.paypal.com/ -> paypal.com) not your backend, so even if you add any headers to your backend or frontend, the problem will persist because the only header that is important when you perform the request to the https://pilot-payflowpro.paypal.com/ is the header from the response of this request.
To solve this problem the https://pilot-payflowpro.paypal.com/ needs to send the correct header response allowing you to perform this request, and I think it's not possible because security reasons.
Some endpoints can't be use from a frontend application, only from a backend, and I think it's your case.
To avoid the CORS problem you can create an endpoint in your backend that call the https://pilot-payflowpro.paypal.com/. So, in your frontend you call your backend endpoint and the backend call the PayPal API.
calling the REST call is one solution. Another solution would be to mask the endpoint URL in the proxy configuration in Angular.
"/paypal" : {
"target" : "https://pilot-payflowpro.paypal.com/",
"secure" : true,
"changeOrigin": true,
"pathRewrite":{
"^/paypal":""
}
}
And calling /paypal where we have to do the REST call.

Access-Control-Allow-Origin Error Only on a Single Route, Only When Deployed to GAE

I'm using google app engine to host both my frontend and my api backend. I'm getting the following errors when I'm polling the "slicingdone" route on my backend:
bootstrap e65cef5bb029055e1719:2 GET
https://playloopsbackend-217106.appspot.com/playloops/slicingdone 502
send # bootstrap e65cef5bb029055e1719:2
/videotogifs:1 Access to XMLHttpRequest at
'https://playloopsbackend-217106.appspot.com/playloops/slicingdone'
from origin 'https://playloopsfrontend.appspot.com' has been blocked
by CORS policy: No 'Access-Control-Allow-Origin' header is present on
the requested resource.
I poll the slicingdone function to figure out when trimming of a video on my backend is finished. It works locally but is presenting the above errors when deployed to gcloud.
slicingdone function on my backend looks like this(Express):
slicingdone(req, res, next) {
if(slicingIsDone == true){
res.status(200).send('true');
slicingIsDone = false;
}else{
res.status(200).send('false');
}
}
*Every other route on my backend works fine even when deployed. I have similar functions on the backend that manipulate videos using ffmpeg in different ways. I have whitelisted my frontend url on my backend, so I'm not sure why I'm getting these CORs errors. I store the video results in google cloud storage--perhaps I need to add my backend url to google cloud CORS whitelist?
Any help is much appreciated! Thank you!

Getting Failed to load resource: the server responded with a status of 404 (Not Found) when pushing Angular app to cloud foundry

I am able to access the client server in Angular 5 from localhost:4200 with Cross-Origin concept but when I am deploying the app using ng build to Pivotal Cloud Foundry, getting error Failed to load resource: the server responded with a status of 404 (Not Found).
Not able to figure out the exact issue.
I am using package.config.json as -
{
"/api": {
"target": "https://benifit.cfapps.io/api",
"pathRewrite": {
"^/api": ""
},
"changeOrigin": true
}
}
Also, I am using cf push -b staticfile_buildpack portal-app for pushing my app to PCF. Please suggest where and what I am missing
You are referring to the proxy config file from angular-cli dev server. This file is only used for local development, to avoid cross-origin requests. You cannot use this proxy, after the app is deployed.
So in your case the Angular app will directly query your backend underneath the following path /api. So you have to ensure the api is available at the same host (in cloud foundry). When the api is only available under benifit.cfapps.io/api, you have to change the base path for your HTTP queries in the app and also take care to enable cross-origin requests on the api side.

How to stop mixed Content browser Error when calling App Engine Flexible Environment API?

I'm getting this error in browser:
Mixed Content: The page at 'https://{my-site}' was loaded over HTTPS, but
requested an insecure XMLHttpRequest endpoint 'http://{my-api}'. This request
has been blocked; the content must be served over HTTPS.
I know I need to allow https some how. The application uses Gunicorn to run the application on custom Google App Engine Flexible Environment. It also uses flask. Here is my app.yaml:
runtime: custom
env: flex
service: flex-module
entrypoint: gunicorn -b :$PORT main:app
Is it possible to change some setting in the Extensible Service Proxy to allow https in App Engine? Or do I need to get an ssl certificate and key and add the following to my app.yaml:
gunicorn -w3 --certfile=server.crt --keyfile=server.key test:app
Also i'm not sure if i need to add this to a gunicorn.conf.py as in this documentation:
forwarded_allow_ips = '*'
secure_scheme_headers = {'X-APPENGINE-HTTPS': 'on'}
Thanks
As stated in the documentation, Google does not issue SSL certificates for double-wildcard domains that are hosted at appspot.com:
Note: Google recommends using the HTTPS protocol to send requests to your app. Google does not issue SSL certificates for double-wildcard domains that are hosted at appspot.com. Therefore, HTTPS requests must use the string "-dot-" as the URL notation, instead of "." for separating subdomains. You can use the simple "." URL notation with your own custom domains and other HTTP addresses. For more information, see the HTTP and HTTPS examples in the following sections.
So to allow API requests over https and avoid the mixed content browser error, instead of http://version-one.my-app.appspot.com I needed to send request to: https://version-one-dot-my-app.appspot.com
To make HTTPS calls, enable the ssl library for your app by adding the following configuration to the app.yaml file:
libraries:
name: ssl
version: latest
https://google-auth.readthedocs.io/en/latest/user-guide.html

Cloud Endpoints Handler SSL redirect blocked by CORS

I would like my Cloud Endpoints API to be called with HTTPS. My app.yaml file contains the following:
# The endpoints handler must be mapped to /_ah/api.
- url: /_ah/api/.*
script: main.api
secure: always
If a client (i.e. website) makes an insecure (HTTP) call to the endpoint URL, App Engine performs a redirect to the secure version (HTTPS)
For example, suppose my App Engine app is at http://api.endpoints.my-app.appspot.com and the API endpoint for making a HTTP GET request to the method mymethod is:
http://api.endpoints.my-app.appspot.com/_ah/api/myapp/v1/mymethod
App Engine redirects to the HTTPS version:
https://api.endpoints.my-app.appspot.com/_ah/api/myapp/v1/mymethod
However, the redirect from is blocked:
blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access.
How can I add the required header to my resource (i.e. my Cloud Endpoints API on App Engine)? Google's documentation states CORS is enabled by default on App Engine Standard - which is what I'm using. So I'm unsure why this is even a problem.
You should be able to configure the Access-Control-Allow-Origin header in app.yml. For your case, please try the following to the app.yml file:
handlers:
- url: /_ah/api/.*
script: main.api
secure: always
http_headers:
Access-Control-Allow-Origin: http://localhost:4000
More to read:
app.yml reference
A related SO question

Resources