Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firebase hosting Access-Control-Allow-Origin for app engine URL

I am hosting a single page app on Firebase hosting and I need to allow cross domain request to app engine. App is hosted at project-id.firebaseapp.com and the app engine service on project-id.appspot.com. I red the deployment documentation and there is no example how to add Access-Control-Allow-Origin header for URL.

Here is what my firebase.json looks like:

{
  "database": {
    "rules": "database.rules.json"
  },
  "hosting": {
    "public": "public",
    "redirects": [
      {
        "source": "/server/:rest*",
        "destination": "https://app-id.appspot.com/:rest*",
        "type": 301
      }
    ],
    "rewrites": [
      {
        "source": "/views/**",
        "destination": "/views/**"
      },
      {
        "source": "**",
        "destination": "/index.html"
      }
    ],
    "headers": [ {
      "source" : "https://app-id.appspot.com/registration/generate",
      "headers" : [ {
        "key" : "Access-Control-Allow-Origin",
        "value" : "*"
      } ]
    } ]
  }
}

I've tried to set the CORS using gsutils but it didn't help as well:

Here is my cors.json

[
    {
        "maxAgeSeconds": 3600, 
        "method": ["GET", "POST"], 
        "origin": ["https://project-id.appspot.com/"]
    }
]

Thanks in advance

SOLUTION:

If all you want is to allow CORS on static files then setting the Access-Control-Allow-Origin header in app.yaml is enough. This header is not allowed to be in app.yaml on dynamic requests so you'll have to add it programatically.

If your request is a simple one then the following code works:

@Override
public void doPost(HttpServletRequest req, HttpServletResponse resp) 
    resp.addHeader("Access-Control-Allow-Origin", "*");
    resp.addHeader("Content-Type", "text/csv");
    resp.getWriter().append("Response");

}

However if your request is pre-flighted you'll have to override the doOptions method and add the appropriate headers:

@Override
protected void doOptions(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    resp.addHeader("Access-Control-Allow-Origin", "*");
    resp.addHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
    resp.addHeader("Access-Control-Allow-Headers", "Content-Type");
}

@Override
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
    resp.addHeader("Access-Control-Allow-Origin", "*");
    resp.addHeader("Content-Type", "text/csv");
    resp.getWriter().append("Response");
}

Here is a helpful diagram which clarifies CORS implementation on server:

like image 635
Jan Beneš Avatar asked Feb 07 '17 16:02

Jan Beneš


People also ask

How do I enable CORS in firebase storage?

CORS Configuration To download data directly in the browser, you must configure your Cloud Storage bucket for cross-origin access (CORS). This can be done with the gsutil command line tool, which you can install from here. Run gsutil cors set cors. json gs://<your-cloud-storage-bucket> to deploy these restrictions.

Can firebase hosting dynamic website?

Stay organized with collections Save and categorize content based on your preferences. Firebase Hosting provides fast and secure hosting for your web app, static and dynamic content, and microservices.

What is link to Firebase hosting site?

Firebase hosting is just that - a hosting service. If you have an existing site with them, you can link it to your web-app using the link to a firebase hosting site button. If you don't link it, you will get the default firebaseapp.com or web. app URLs assigned to your web app.


1 Answers

Your firebase.json does not control appspot.com files and can't be used to modify headers from your app engine service. Here, you've tried to set Access-Control-Allow-Origin on https://app-id.appspot.com/registration/generate. That's not going to work since that's not a page hosted at Firebase Hosting.

Instead, the way you would add a header to a Firebase page would be to put it in the firebase.json like so:

"headers": [ {
  "source" : "index.html",
  "headers" : [ {
    "key" : "Access-Control-Allow-Origin",
    "value" : "*"
  } ]
} ]

But that's not going to help with the CORS issue, since it needs to be in place on the returned resource.

It looks like you can put it into your app.yaml under handlers based on this doc.

handlers:
- url: /.*
  http_headers:
    Access-Control-Allow-Origin: http://mygame.appspot.com

Also, you can add this programatically. As explained on enable-cors.org, here are some script implementations:

For Python-based applications in Google App Engine, the self.response.headers.add_header() method can be used, such as:

class CORSEnabledHandler(webapp.RequestHandler):
  def get(self):
    self.response.headers.add_header("Access-Control-Allow-Origin", "*")
    self.response.headers['Content-Type'] = 'text/csv'
    self.response.out.write(self.dump_csv())

For Java-based applications, use resp.addHeader():

public void doGet(HttpServletRequest req, HttpServletResponse resp) {
  resp.addHeader("Access-Control-Allow-Origin", "*");
  resp.addHeader("Content-Type", "text/csv");
  resp.getWriter().append(csvString);
}

And for Go-based applications, use w.Header().Add():

func doGet(w http.ResponseWriter, r *http.Request) {
  w.Header().Add("Access-Control-Allow-Origin", "*")
  w.Header().Add("Content-Type", "text/csv")
  fmt.Fprintf(w, csvData)
}
like image 67
Kato Avatar answered Oct 08 '22 14:10

Kato