firebase / firebase-tools

The Firebase Command Line Tools
MIT License
3.99k stars 920 forks source link

allow https for local testing #1908

Closed ultraGentle closed 4 years ago

ultraGentle commented 4 years ago

Hello, this is a CLI-specific feature request, so I'm submitting it here rather than through the general Firebase channel.

Scenario I'm attempting to test a Stripe integration using the local emulator, but I can't because Stripe considers the Firebase emulator insecure. (Details at bottom.)

Current workaround is to deploy on every change, but this is slow and makes viewing logs difficult.

Due-diligence Googling reveals that there are ways of serving localhost over https -- which I am also attempting -- but I thought it was worth noting here, because one of the reasons I turned to Firebase was the ease of onboarding, and all-in-one workflow. Other users like me (less experienced with backend or devops) may benefit from having this built in.

Feature request: serve by default over https, or at least allow it with a flag.

For reference / reproducibility see https://github.com/stripe-samples/checkout-single-subscription/tree/master/client-only/client
specifically, in index.html, change the successUrl near the bottom to localhost:5000 for use with the Firebase emulator. Then go through the Checkout process successfully, and you'll get the SSL: not secure error on redirect back to localhost.

samtstern commented 4 years ago

@ultraGentle thanks for the feedback! We've investigated a few ways of serving https on Localhost but it's basically not possible to do cross-platform through an unprivileged Node.js process.

Have you looked into using something like ngrok or another local proxy to create an HTTPS tunnel to your emulator?

ultraGentle commented 4 years ago

Thanks for your response! I've been looking into solutions for the last couple of hours, such as the one you mentioned, but this is my first contact with any of the involved tools or commands, so it's a bit overwhelming! (This is no fault of FIrebase, of course.)

My main concern is to not expose anything that shouldn't be exposed, either from my project or from my local system, and it's hard to know what's legit.

I won't ask for "how-to" advice here, but before going down the ngrok route (which sounds like it will require quite a bit of config), I will just ask a simple yes/no:

Do you know whether https://github.com/FiloSottile/mkcert (22k stars), which purports to be zero-config https localhost, will achieve this?

Of course it's fine if you can't comment on external services, or if that's too out-of-scope.

mbleigh commented 4 years ago

Something to keep in mind is that Stripe won't be able to send webhooks to your HTTPS localhost anyway -- localhost is a URL that only works on your computer, so you'd need to put it somewhere on the internet regardless.

ultraGentle commented 4 years ago

@mbleigh Good point! I hadn't thought of that. But it turns out Stripe has a CLI to forward webhooks to your local server: https://stripe.com/docs/stripe-cli

And for me the specific issue was testing step 3 here:

  1. user arrives at Firebase web app,
  2. user is redirected to Stripe Checkout,
  3. [fails only when emulated] user is re-redirected back to /success.html page at original domain.

In any case, thanks for the feedback!

samtstern commented 4 years ago

@ultraGentle thanks for the pointer to the Stripe CLI! I will take a look at their code and see if there's anything I can learn about this. But for now I am going to close this issue as infeasible / out of scope.

As for your other questions: a) I have heard good things about mkcert but as @mbleigh said it still won't help get your localhost services exposed off your local network. b) It's been a while since I used ngrok but it was actually pretty easy, just a single command once I got my API key and all that.

ultraGentle commented 4 years ago

@samtstern You're right, ngrok isn't so bad -- thanks for the pointer. It's a pleasure discoursing with you guys!

ronnyli commented 3 years ago

thank you for the ngrok suggestion, it solved more than just this problem for my team!

pirzol commented 2 years ago

Hi all,

I have tried the ngrok solution to connect to realtime db emulator. The issue I encounter was that there is no way to configure the protocol of the connection, only the domain - db.useEmulator("localhost", 9000); This is true only for the realtime emulator, The authentication emulator for example does allow configuring the protocol. My app uses both, firebase realtime db and authentication, Using the emulator just for the authentication and realtime db with a real firebase instance only complicates my app so it wasn't worth it.

Thaina commented 2 years ago

@ultraGentle thanks for the feedback! We've investigated a few ways of serving https on Localhost but it's basically not possible to do cross-platform through an unprivileged Node.js process.

Have you looked into using something like ngrok or another local proxy to create an HTTPS tunnel to your emulator?

At least I have seen local-web-server on npm doing well on --https under Windows. It's fine for us to have insecure page that need to press advance in browser. Or are there any more than that firebase need to do?

github0013 commented 2 years ago

Using v9 connectFirestoreEmulator, it is really not possible to use HTTPS since ssl is set to false.

https://github.com/firebase/firebase-js-sdk/blob/1cf124e6ef0c7f921bea018cd638ea17dcfaa991/packages/firestore/src/lite-api/database.ts#L252

th0rgall commented 1 year ago

EDIT July 15th '24: this is actually a new feature request (allow connecting to HTTPS-hosted emulators). I just made a corresponding feature request in Firebase's official UserVoice tool. Please go upvote that one for visibility! I don't think this comment will have any effect.

ngrok is also not a solution for me, for the same reasons @pirzol & @github0013 pointed out above. Only the Auth emulator can connect to a https host.

The Firestore, Storage and Functions can not (I'm not using Pub/Sub or Hosting emulators).

My feature request is not serving emulators over HTTPS (ngrok can work around that), but allowing connecting to https-hosted emulators from the Firebase (web) client.

My use-case: I'm trying to debug Web Push functionality via FCM using emulators. Web Push only works with Service Workers, which only work on localhost (http/https doesn't matter), or an arbitrary https-enabled host.

When testing Web Push on a real mobile iOS or Android device on my local network, I can not use localhost. I must serve my client app over https (with a mkcert cert) to the local network, but browsers generally block downgraded https -> http protocol requests. Because the Firestore, Storage and Functions emulators only work over http, this renders the app untestable. For example, Chrome gives this error:

fetcher.js?v=2f821d7e:54 Mixed Content: The page at 'https://10.150.7.36:5173/sign-in' was loaded over HTTPS, but requested an insecure resource 'http://10.150.7.36:9099/identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key='. This request has been blocked; the content must be served over HTTPS.

I suppose my workaround will be to test with a staging Firebase project without emulators, which is much less convenient; especially since I need to deploy every change to test it, rather than leveraging live reload.

JZubero commented 8 months ago

@samtstern Do you consider this resolved? Since there is no option to enable ssl when connecting to the emulator (@github0013 pointed to the relevant code), using ngrok does not solve the issue.

JZubero commented 8 months ago

@github0013 @th0rgall Looks quite hackish but could be OK for local development.

const db = getFirestore();
connectFirestoreEmulator(db, location.hostname, 8484);

// @ts-ignore
db['_settings']['ssl'] = true;

This should enable the ngrok approach. We are testing this today.

dzivoing commented 5 months ago

Any news on enabling https for emulators ? I am developing office addin and i can only load https based urls so this breaks my local development env

timbicker commented 5 months ago

I have exactly the same problem....

sergiocampama commented 5 months ago

adding myself to the list of people blocked by this, specifically for storage, as I need to develop with taking images from the camera, and that is only allowed from https sites

luckyape commented 4 months ago

I find myself reflecting daily on the incredible progress in web development, and it's clear that Firebase has played a significant role, thanks to the immense effort and creativity poured into it. While I'm truly thankful for the platform you've created, there's this small but crucial functionality gap that I find quite challenging and seems to be a stumbling block for many common scenarios. The issue can present itself well into the dev cycle making it a bigger work around than it should be. Keep up the great work!

alexpchin commented 2 months ago

@github0013 @th0rgall Looks quite hackish but could be OK for local development.


const db = getFirestore();

connectFirestoreEmulator(db, location.hostname, 8484);

// @ts-ignore

db['_settings']['ssl'] = true;

This should enable the ngrok approach. We are testing this today.

Any update on this?

I am building a PR preview workflow where the firebase emulators are deployed to CloudRun. I'm using a proxy server to redirect requests to the various emulator ports (as CloudRun is only exposing 8080).

Everything works amazing locally but when it's deployed, it's not connecting to the database?

Any suggestions?

xantin commented 2 months ago

What about to use Stripe CLI, something like

  1. stripe login install
  2. stripe listen --forward-to http://localhost:5001/ext-firestore-stripe-payments-handleWebhookEvents
th0rgall commented 1 month ago

@xantin the Stripe CLI was already discussed here https://github.com/firebase/firebase-tools/issues/1908#issuecomment-573065544. It's a workaround to make HTTP work with Stripe, but it doesn't help if you actually need HTTPS in other situations.

For people still bumping into this issue today, I noticed that my comment https://github.com/firebase/firebase-tools/issues/1908#issuecomment-1677219899 got 6 upvotes. Upvotes here won't help to get HTTPS support, so please upvote the related feature request in Firebase's official UserVoice tool.