How to enable CORS with Cloud Endpoints? - google-app-engine

Is there a slick way to enable CORS with the Cloud Endpoints?
(Adding "Access-Control-Allow-Origin: *" or something like this to the response)
Thanks,
Brandon

As CORS works on production for Cloud Endpoints. What I did to test on devserver (local) was to disable the browser security. For Dartium (I think Chrome also) use --disable-web-security parameter on startup.

Try adding this to the yaml file of your endpoint:
x-google-endpoints:
- name: "{your-endpoint-host-name}"
allowCors: "true"

This depends on if you have control over the headers on the endpoints - either via the application or the web server serving the original page which contains scripts that want to make cross domain requests.
JSON-P still seems far more popular - either due to lack of support on the server side of platforms, or a distrust that it will work with clients (e.g. legacy web browsers) - whereas JSON-P will often work.

Related

Quarkus REST API CORS configuration not working for consumer ReactJS app

I have a ReactJS UI that is served by a static NGINX web server and a Quarkus REST API server. Both are dockerized services, and the ReactJS app is supposed to use the Quarkus REST API to consume data/make requests. In the depiction below we can see this simple setup for my localhost dev enironment (both services are exposed and mapped to different localhost ports):
In the deployed production environment, these will services will likely correspond to different hosts/URLs. The problem is, even in the localhost setup i expectedly have the issue of CORS errors when i try to make calls to the REST API service from the ReactJS app running in the clients browser, e.g. during login:
I have to admit, i dont fully understand CORS in terms of where exactly one has to make changes/configs to allow them - but i was told i need to set them in the server i make requests to (which in this case is the Quarkus REST API). So i added this setting in the Quarkus app application.properties to just generally allow all requests:
quarkus.http.cors=true
(as shown in https://quarkus.io/guides/http-reference#cors-filter)
In reality i should probably change this to be more precise, however i still receive the same CORS error in my browser when running the react web app. I understand that i could also configure a proxy in the NGINX server to tunnel requests to the other service container potentially, but i would like to solve this through CORS configuration. Where do i have to make which configurations for this to work? Did i make a mistake with the Quarkus config?
It seems you cannot only set quarkus.http.cors=true for it to work and allow all requests, as per the Quarkus documentation. In my case i had to add more configurations, i.e.:
quarkus.http.cors=true
# This allows all origin hosts, should be specified if possible
quarkus.http.cors.origins=*
quarkus.http.cors.headers=accept, authorization, content-type, x-requested-with
quarkus.http.cors.methods=GET, POST, PUT, DELETE, OPTIONS

How to force https on Google Cloud AppEngine

I am trying to force https for all traffic to an app hosted on Google Cloud AppEngine. https works, but despite following the instructions for rewriting http traffic to https, it's still possible to access the site with http, which causes problems.
I have added this to the app.yaml:
handlers:
- url: /.*
script: _go_app
secure: always
redirect_http_response_code: 301
but it doesn't seem to make any difference.
I am using the julienschmidt router and then this to handle all routes:
log.Fatal(fmt.Println(http.ListenAndServe(":8080", router)))
I have looked at using http.ListenAndServeTLS but this takes extra parameters and I can't work out what the values of those should be in the Google AppEngine context.
log.Fatal(fmt.Println(http.ListenAndServeTLS(":8443", "cert.pem", "key.pem", router)))
Where are "cert.pem" and "key.pem"?
I've read that I don't need to explicitly serve TLS in my app, because AppEngine will handle it for me, so even if I knew what the parameters were, I'm not sure it would help in forcing https.
http://sapling.appspot.com
https://sapling.appspot.com
http://sapling.money
https://sapling.money
All of the above work, but I don't seem able to force either of the http versions to https.
If you are using the secure:always handler and the requests are not being automatically redirected, then you are probably using App Engine Flex?
App Engine Flex does not support handlers, you can see this in the Flexible app.yaml documentation.
Instead, you can check in your code if a request was sent via HTTP or HTTPs and redirect. This is done with the App Engine specific header X-Forwarded-Proto.
The implementation is configured on your end and there is a brief paragraph on the subject.
You can also view similar Stack posts with the same answers 1
I hope this helps!
You are correct for including the secure: always element in your app.yaml as this will force HTTPS for your app's handlers.
However, I believe the following App Engine Documentation for "Securing Your App" found here may be of some use to you. As indicated in that link, you can convert HTTP URLs to HTTPS by simply replacing the periods between each resource with a -dot- instead. You may see the example provided below.
http://[SERVICE_ID].[MY_PROJECT_ID].appspot.com
https://[SERVICE_ID]-dot-[MY_PROJECT_ID].appspot.com
For additional information about HTTPS URLs and resource targeting you may see how requests are routed here.
Hope this helps!
You can use the Strict-Transport-Security header to instruct the browser to prefer https over http for a given page or an entire domain as outlined in this document. In order to add HTTP Strict-Transport-Security headers (HSTS) to your app, you must implement the headers within your app's code, not within your app's config file (app.yaml or appengine-web.xml).
It is also a good idea to enable HSTS preloading if you register your application with Google's HSTS preload list. Firefox and Chrome will never load your site over a non-secure connection.

Got "DatastoreException: Request is missing required authentication credential" if using Objectify 6.0 and <url-stream-handler> at the same time

On an App Engine application, deployed on standard environment with java 8 activated, I get the exception below if I use both Objectify 6.0 AND the tag <url-stream-handler>urlfetch</url-stream-handler> in the appengine-web.xml file.
com.google.cloud.datastore.DatastoreException: Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.
Any idea how I can bypass that?
Things get back to normal if I remove the urlfetch tag (and activate the billing) or if I downgrade Objectify to v5.
I suspect what you're running into is one of the differences between the Java 7 and the Java 8 Standard Environments. There are substantial benefits to avoiding the urlfetch path, as Issuing HTTP(S) Requests notes (e.g. HTTP/2). In particular, the metadata server, which does automatic authentication for the Google Cloud SDKs when running on App Engine, isn't reachable using urlfetch (see that page).
I think your best option here is probably to enable billing, if you're comfortable with that. From the docs page:
Despite the requirement to enable your application for billing, your app won't incur any more cost than the same application running on Java 7.
If you'd still like to give urlfetch a try, I think the error you're encountering can be fixed by manually supplying credentials (e.g. bundling them in your app), but that won't be as secure or performant.
The best option is to use the
<appengine-web-app>
<url-stream-handler>native</url-stream-handler>
<appengine-web-app>
and enable billing. Without billing you can only use the legacy urlfetch and you have to face all these problems.
you can set credentials explicitly, like it is shown in the example below:
Resource credentialsCyberpower = resourceLoader.getResource("classpath:yourservice-datastore-access.json");
GoogleCredentials credentials = GoogleCredentials.fromStream(credentialsCyberpower.getInputStream())
.createScoped(Lists.newArrayList("https://www.googleapis.com/auth/cloud-platform"));
DatastoreOptions options =
DatastoreOptions.newBuilder().setProjectId("XXXXXX").setCredentials(credentials).build();
Datastore datastore = options.getService();
ObjectifyService.init(new ObjectifyFactory(datastore));
generate yourservice-datastore-access.json in IAM service accounts. working with Objectify 6.0.5

Correctly assign HTTPS only custom domain to flex env

What is the correct way to map a custom domain to Google App Engine project?
I've added the custom domain, set up all the DNS records etc. and it is working! But how do I enforce HTTPS only? (Like the custom domain generated does)
From reading around many posts I have seen secure: always in a handler which I have tried, but doesn't seem to work (saw some comments that it doesn't work on flex environments?)
So how can I correctly map my domain to a flex php environment being HTTPS only?! Seems such a simple thing to want to be able to do!
While being somewhat related to a custom domain (for example the SSL certificate used by HTTPS being tied to the domain) the HTTPS-only behaviour is not really an attribute of the custom domain mapping operation, it's just a behaviour of the app itself (regardless of being mapped to a custom domain or not).
For standard environment GAE apps part of the HTTPS-only behaviour is an automatic http -> https redirection performed by the GAE infra on behalf of the app if secure: always is set in the app.yaml configuration file.
But that configuration has, indeed, been deprecated for the flexible environment GAE apps. The PHP-specific deprecation note can be found at app.yaml changes:
Secure handlers
The secure setting under handlers is now deprecated for the App
Engine flexible environment. If you need SSL redirection, you can
update your application code and use the X-Forwarded-Proto header to
redirect http traffic. You can also use the HTTP Strict Transport
Security response header.
You'll also note that there is no mentioning of secure (or handlers for that matter) in the app.yaml Configuration File doc.
So you need to take care of the http -> https redirection inside your app code (or the framework you use for it, if any and if it has such capability), possibly following the suggestions from the above quote. I can't really help with details on this as I'm not a PHP user.

urlfetch.fetch() from Google App Engine not showing up in Fiddler2

I'm testing a Google App Engine app on my Windows machine, running locally on localhost:8084. Fiddler2 shows all my activity when I navigate around my app, but when requesting an external url with urlfetch.fetch() it doesn't show up in Fiddler at all, even when using an http, not an https address, and with a successful status code 200 in the response.
What do I need to do to get the urlfetch.fetch() request from Google App Engine to show up in Fiddler2?
My understanding is that Fiddler2 runs as an HTTP proxy; browser requests go through this proxy instead of directly to the internet resource. This allows Fiddler2 to capture information about the request and the response.
According to the Fiddler2 docs, "You can configure any application which accepts a HTTP Proxy to run through Fiddler so you can debug its traffic". So I think you would need to change the URLFetch API call to use a proxy, supplying the Fiddler URL and port. However, the URLFetch documentation doesn't specify exactly how to do this. You might be able to use urllib2 as specified in this question.
Irussell is generally right, but I'd like to make the answer more specific.
As proxies aren’t supported within Google AppEngine production environment, it’s not directly supported by development engine either. It seems that the only way to overcome this limitation is to modify the code of AppEngine development server.
You'll have to modify the urlfetch_stub.py file, by adding the following lines:
connection = connection_class('127.0.0.1', 8888)
and
full_path = protocol + "://" + host + full_path
You may find the detailed explanation in my blog post Use Fiddler to debug urlfetch requests in Google AppEngine

Resources