vuejs / vuefire

🔥 Firebase bindings for Vue.js
https://vuefire.vuejs.org
MIT License
3.86k stars 333 forks source link

Read protected by security rules documents in SSR #1310

Closed niklv closed 1 year ago

niklv commented 1 year ago

What problem is this solving

Currently it rejects with%

[nitro] [dev] [unhandledRejection] [FirebaseError: Missing or insufficient permissions.] {                                                                                                                                                                         11:55:59
  code: 'permission-denied',
  customData: undefined,
  toString: [Function (anonymous)]
}

Proposed solution

Somehow init firebase-js-sdk auth in SSR with provided from client idToken?

Describe alternatives you've considered

No response

posva commented 1 year ago

I don't understand what you mean. A reproduction could help

niklv commented 1 year ago

@posva

  1. Protect some collection with firestore security rules (for example /content/{contentId}). Make it available for logged in users only.
  2. Login/Create user in Vue app with anonymous provider for example.
  3. If you request collection /content/{contentId} from frontend it will be available.
  4. If you request collection inside SSR it will throw error FirebaseError: Missing or insufficient permissions.

If this is not clear I can try create repoduction repo for you.

posva commented 1 year ago

You need to configure the server to handle authentication which is not an easy task. The nuxt plugin handles most of it automatically, did you check it: https://github.com/vuejs/vuefire/tree/main/packages/nuxt ?

niklv commented 1 year ago

@posva yes, I check it Auth validation works well in SSR. I need to query with user auth protected collections in SSR, this is what this issue is about

LoicNuom commented 1 year ago

I have the same issue, always getting the error during SSR

[nitro] [dev] [unhandledRejection] [FirebaseError: Missing or insufficient permissions.] {                       
  code: 'permission-denied',
  customData: undefined,
  toString: [Function (anonymous)]                                                                                   
}

I'm using Nuxt 3, I have setup the service account and I'm getting the authentication fine but I'm not able to query protected documents.

If it's not possible defines what to do when an error happens? right not it is just stoping the page rendering

LoicNuom commented 1 year ago

@posva I was able to reproduce the issue on your demo repository: https://github.com/posva/vuefire-nuxt-example

Navigating to /firestore-secure-doc works fine: image

but reloading the page creates an error: image image

I have tried multiple versions of nuxt-vuefire between 0.0.19 and 0.1.6 with the same results

chrisspiegl commented 1 year ago

Hi, I have run into a similar issue. Have you tested this in different browsers? I had this happening in Chrome in an Incognito window. When I was using Chrome in a normal window it works. In Firefox and Safari I don't remember but I feel like it was different in one of them.

So maybe test that and see if any version works?

niklv commented 1 year ago

@chrisspiegl it is ssr backend issue. Not related to browser version. It depends on browser firebase auth token exist or not and how it handles inside ssr.

LoicNuom commented 1 year ago

@chrisspiegl tried and Chrome and Firefox without success. It only works in Safari because for some reason useCurrentUser() always return undefined during SSR on Safari.

I have a fix, but it is not really elegant:

image
niklv commented 1 year ago

@LoicNuom it is dangerous, cause it bypass security rules. You read document via firebase-admin in your workaround. It maybe ok there, cause path maybe contains uid, but in other cases it will be security issue.

LoicNuom commented 1 year ago

Yes that's why I said it wasn't an elegant solution. But because the code is ran on a server, I don't think we can use the client SDK to and pretend to be a specific user

niklv commented 1 year ago

@LoicNuom actually you can, the only problem is intialization client sdk on server with client idToken, that you receive via cookie. If firebase auth not used (aka user not logged in) and security rules allow access to all user, all works fine. Error FirebaseError: Missing or insufficient permissions recevies in SSR from firebase client sdk. Also check support table: https://firebase.google.com/docs/web/environments-js-sdk#other_environments

LoicNuom commented 1 year ago

Yes, the issue is that requests made using the client SDK on the server are not authenticated. And I don't think there is a simple way to authenticate those requests as a specific user.

robokozo commented 1 year ago

Just ran into this myself. I'm wondering how I can work around this temporarily. Any ideas?

niklv commented 1 year ago

@posva there are repo link there in thread above, please change issue label

posva commented 1 year ago

No need to ping me: I'm currently busy with other stuff and I will check again in end-may

Maxino22 commented 1 year ago

Just ran into this error... any fixes now??

dword-design commented 1 year ago

I also have this issue! :)

niklv commented 1 year ago

@michael-strain My firestore rules allow document read only for authenticated users. The issue happen inside SSR. On client side all works fine.

niklv commented 1 year ago

@posva is there any chance that you will check this issue?

posva commented 1 year ago

I updated quite a few things in the recent releases and couldn't reproduce the bug anymore. I suspect you are missing the service account file and configuring it

It's normal it doesn't work for you when testing locally this project because you don't have access to the service account

Maxino22 commented 1 year ago

Hey, I also noticed I was getting missing service account files locally... let me update and test... Thanks

dword-design commented 1 year ago

It's still an issue for me with current dependencies. I think the issue is that we are not logging in server-side with the client sdk.

posva commented 1 year ago

I think I found the issue: the firestore instance is not using the correct application instance that is connected to the logged in user

It was more complicated than that: it was necessary to create a custom token on the server but it's not really that well documented 😅

dword-design commented 1 year ago

@posva That's great, can confirm that it works! 🎉