Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nuxt 3 App With Vuefire: Getting an (auth/login-blocked) error in production with SSR #1408

Closed
johnpuaoi opened this issue Aug 15, 2023 · 27 comments

Comments

@johnpuaoi
Copy link

Reproduction

https://github.com/johnpuaoi/vuefire-auth-blocked

Steps to reproduce the bug

  1. Replace the firebase config with your own.
  2. Create an ENV and add the GOOGLE_APPLICATION_CREDENTIALS
  3. Build the nuxt 3 app with pnpm build
  4. Run node .output/server/index.mjs --host 0.0.0.0
  5. Open localhost:3000
  6. Attempt to sign in with a user account on app.vue main page

Expected behavior

After signing in the user information should be displayed. The sign in should not be blocked.

Actual behavior

The sign in is blocked and an error is shown.

Additional information

This only happens when SSR is enabled and you build for production, in dev mode this does not happen at all. If you disable SSR then everything works as should in production.

The credentials are set using the GOOGLE_APPLICATION_CREDENTIALS env var which is an object of the service key. I tried setting the var to be a path to serviceKey.json file but still the same error.

This is the error that is returned: Error minting the cookie FirebaseAppError: Credential implementation provided to initializeApp() via the "credential" property failed to fetch a valid Google OAuth2 access token with the following error: "Error fetching access token: Error while making request: getaddrinfo ENOTFOUND metadata.google.internal. Error code: ENOTFOUND".

For now I will release my nuxt 3 apps as an SPA until this can be resolved. I attempted to take a crack at this issue by inserting some console.logs in the ensureAdminApp function to check the credential but can't seem to narrow down the issue.

Again this only happens if your using SSR with nuxt and you build for production. SSR in dev mode works just fine with nuxt-vuefire.

Copy link
Member

posva commented Aug 15, 2023

This usually means a misconfiguration on the Firebase project or that you have something blocking the login. BTW your reproduction is private

@posva posva added the need repro label Aug 15, 2023 — with Volta.net
@johnpuaoi
Copy link
Author

Shucks so sorry about that, didn't realize I had set that repro to private, just made it public now. If its a misconfiguration in firebase, do you have any clue as to what I should be looking for?

When I had deployed my site to netlify and first encountered the issue, I was using the nuxt-security module, so I thought that somehow the nuxt-security module was blocking the auth request but even with that module removed, the issue still persists.

Appreciate whatever insight you have on this, apologies for the private repro again. Have a wonderful and blessed rest of your day/night🤙

@luc122c
Copy link
Contributor

luc122c commented Aug 15, 2023

This is the error that is returned: Error minting the cookie FirebaseAppError: Credential implementation provided to initializeApp() via the "credential" property failed to fetch a valid Google OAuth2 access token with the following error: "Error fetching access token: Error while making request: getaddrinfo ENOTFOUND metadata.google.internal. Error code: ENOTFOUND".

getaddrinfo ENOTFOUND is simply Node.js' way of telling you that it can't connect to an address. It seems as if it is reaching out to the metadata server to fetch a token, but can't connect to it?
What platform are you hosting on? If you're hosting on Firebase / Google Cloud then you should have no problem reaching it. If you're on another platform, it won't work.

Metadata server info:

@johnpuaoi
Copy link
Author

@luc122c Thank you for the info. I am deploying to netlify but I did not realize that I would need to deploy to a google environment. I thought that as long as I set the GOOGLE_APPLICATION_CREDENTIALS env var manually, meaning setting the value as the json object rather than a path to a json file, then I'd be good to go. I got the impression from this tip in the docs: "When deploying outside of Firebase, the GOOGLE_APPLICATION_CREDENTIALS environment variable has to be set manually. Instead of setting it to the path of the service account file, you can set it to the content of the file itself. Note it will have to fit in one single line."

@luc122c
Copy link
Contributor

luc122c commented Aug 15, 2023

@johnpuaoi Sorry for any misunderstanding, you should still be able deploy this to non-firebase hosting, however the metadata server is only available on GCP.

Looking at the code, it would seem that the env variable isn't available and it's falling back to applicationDefault() which would contact the metadata server, which isn't available on netlify.
You could try setting FIREBASE_PROJECT_ID, FIREBASE_CLIENT_EMAIL and FIREBASE_PRIVATE_KEYinstead of GOOGLE_APPLICATION_CREDENTIALS. (see here)

@johnpuaoi
Copy link
Author

No worries, I appreciate the help and insight, I see now. I tried using just the other 3 variables before but I would end up getting this error: The default Firebase app does not exist. Make sure you call initializeApp() before using any of the Firebase services.

I'm also getting the warnings in console about not providing a service account which I believe stems from this line in the nuxt-vuefire module:

 const hasServiceAccount =
      typeof process.env.GOOGLE_APPLICATION_CREDENTIALS === 'string' &&
      process.env.GOOGLE_APPLICATION_CREDENTIALS.length > 0

@dosstx
Copy link

dosstx commented Aug 16, 2023

I had that issue when deploying to Netlify. Something was going on witih the Netlify function used to host the website (getting a weird 502 error from /api/_session. This caused Firebase Auth to not like that and blocked the auth logins. I wonder if something similar is happening to your instance? Have you tried to deploy to Netlify and see if your problem happens there, as well?

Another time, I noticed that I was always trying to deploy to Netlify Edge and since that is a Deno runtime, it will not be compatible with firebase-admin dependency (that is a Node based API) which is used by firebase auth during SSR.

@johnpuaoi
Copy link
Author

@dosstx Thank you for the info and yes I have tried deploying to Netlify with SSR enabled but I get the same error as when I run the site in production locally. I see that 502 error as well when using SSR in prod.

I have the site that I encountered this error deployed on Netlify but with SSR set to false and auth works there. If possible, could someone use my repro link, add their own firebase config including the env var and then attempt to build the nuxt site and run locally. Then attempt to sign in, If the error persists, I could then rule out a firebase config error that's causing this.

@dosstx
Copy link

dosstx commented Aug 16, 2023

The 502 api session error is on Netlify, but it is a 404 on Vercel. Also, to make it more weird, some of the vercel preview links work and I have no issue with the firebase auth block (the green arrow version of the URL works):

image

I have double checked that all those domains are whitelisted in firebase auth console. Not sure why the green arrow version works....it's the same code!

Btw, I've had this all working fine on Netlify until recently. For some reason the firebase auth block started a week ago or so for me.

Here's the error I get in browser console when viewing the page:

entry.0faff0d5.js:1 
        
        
        POST https://<site>.com/api/__session 502
s @ entry.0faff0d5.js:1
i @ entry.0faff0d5.js:1
Dc @ entry.0faff0d5.js:3159
await in Dc (async)
(anonymous) @ entry.0faff0d5.js:1205
Promise.then (async)
registerStateListener @ entry.0faff0d5.js:1205
onIdTokenChanged @ entry.0faff0d5.js:1205
_f @ entry.0faff0d5.js:1520
(anonymous) @ entry.0faff0d5.js:3159
(anonymous) @ entry.0faff0d5.js:1
r @ entry.0faff0d5.js:1
runWithContext @ entry.0faff0d5.js:1
HI @ entry.0faff0d5.js:1
runWithContext @ entry.0faff0d5.js:1
MI @ entry.0faff0d5.js:1
FI @ entry.0faff0d5.js:1
await in FI (async)
sm @ entry.0faff0d5.js:3166
(anonymous) @ entry.0faff0d5.js:3166
entry.0faff0d5.js:1  Uncaught (in promise) FetchError:  (502  (/api/__session))
    at async i (entry.0faff0d5.js:1:93560)
    at async Dc (entry.0faff0d5.js:3159:844)

Copy link
Member

posva commented Aug 17, 2023

Could you check https://github.com/posva/nuxt--vuefire-example-blaze-plan? I collected as many instructions as possible when deploying tests apps. It could also be related to deploying to vercel instead of firebase. There are plans to check other providers but at the moment I only have time to focus on Firebase.
On a personal note, I think you should give Firebase hosting and functions a try, the deployment is easier given that everything is on Firebase

If your application is not serving an /api/__session after deployment it means you don't have ssr on the deployed version as that endpoint is added by nuxt-vuefire to handle cookie minting

Regarding auth block, I would check that with Firebase and dive deeper in logs. Normally, it shouldn't be related to vuefire

@dosstx
Copy link

dosstx commented Aug 18, 2023

@posva OK I cloned the nuxt vuefire template from you and deployed to Firebase and and I get the SAME firebase auth blocked / 502 etc errors as mentioned above in the threads:

image

image

I confirmed that the domain is whitelisted in auth settings in firebase console.

The only changes I made from your template are:

  1. Updated the .firebaserc file with my project id
  2. Removed database.rules.json, firestore.indexes.json, firestore.rules, storage.rules because I am not using those features
  3. Removed appCheck from nuxt.config
  4. Updated vuefire config with my own config in nuxt.config

Note: I did enable the IAM Service Account Credentials API for my project, however, I did not understand how I needed to do this part from your template README ---> "Once this API is activated, you will need to add a role to your service account. This is explained in the Firebase documentation." <--- So, I did not do that step . I mentioned this in case it could be the culprit for these errors because I also did not do that in my real world project.

I THINK I correctly set up the emulators and was able to login using localhost:3000 when testing (clicked the auto generate user button), but AUTH does not work on firebase deployed site.

Here is my live demo URL: https://nuxt-vuefire-2576f.web.app/ . You can see there is a 404 not found when trying to use the LOGIN link as well as the firebase auth error when going back to the LOGIN page.

Here is my forked repro from your template: https://github.com/dosstx/nuxt--vuefire-example-blaze-plan/tree/error

Appreciate you looking into this! It doesnt' seem to matter if you host on Firebase, Netlify etc all the errors appear the same.

Copy link
Member

posva commented Aug 18, 2023

You might need that step you skipped but not sure. You could also try deleting the function and redeploying again. A part from that, i can’t tell… You might want to reach out to support

@dosstx
Copy link

dosstx commented Aug 19, 2023

I submitted a ticket to Firebase Support. Will keep this thread updated. If anyone else is able to take the Nuxt template and verify the issue exists, it would be greatly appreciated. Like @posva said, you may need to add a role to the service account (I skipped that step) and that could fix the problem.

@dosstx
Copy link

dosstx commented Aug 22, 2023

Firebase support was unable to help. I ended up removing Vuefire/Nuxt-Vuefire for now and just using the standard Firebase Auth SDK as that works. When I get more time I'll try again.

Copy link
Member

posva commented Aug 22, 2023

I think I should add a method to allow disabling ssr auth as it requires some extra steps to handle but it will still error with a different error if you try to ssr a page that uses data that require authentication

@Kiansa
Copy link

Kiansa commented Aug 22, 2023

I agree!

In most common use cases, SSR is not needed on pages that require authentication.

In my case (a saas application), I use hybrid rendering. all my public pages are SSG and the software routes are SPA because we don't need SEO for that.

Having an option to disable SSR Auth and handling token on a "Persistent cookie" on client side would be great for use cases like mine.

@dosstx
Copy link

dosstx commented Aug 22, 2023

My index page was prerendered at build time -- no auth being used there. However, the problem starts at that point because the Vuefire module is being called (ie, nuxt.config and the auth: true property). Remember, the api/__session 404/502 issue happens immediately on site load. I forgot to check what happens if auth: false is set.

Btw, thanks @posva for all your work on this module. I still use it on other apps. It's great.

Copy link
Member

posva commented Aug 22, 2023

The auth endpoint should be disabled during pre-rendering or ssg as there is no session at that moment

I’m glad you’re not ditching it completely 😄

@Kiansa
Copy link

Kiansa commented Aug 23, 2023

I forgot to check what happens if auth: false is set.

I've just checked that and it disables auth completely. So far the only way to temporary solve this issue is what @johnpuaoi suggested which is setting SSR to false.

@posva
Copy link
Member

posva commented Aug 28, 2023

#1419

@posva posva closed this as completed Aug 28, 2023
@dosstx
Copy link

dosstx commented Sep 7, 2023

I saw this is closed. Does that mean this auth blocked issue is a not a problem anymore?

@MarkSonn
Copy link

hi @posva i'm just wondering if there is an update on this?

i'm trying to deploy my SSG app and i can't even get it running locally after generating it with yarn generate and running it with npx serve .output/public

this is what i get:
image

my app only needs to use signInWithCustomToken from the auth module. i'm just wandering why this needs a service account out of interest? anyway i've tried setting the GOOGLE_APPLICATION_CREDENTIALS to the path and the JSON blob itself and neither work :/ any help would be massively appreciated!

@posva
Copy link
Member

posva commented Sep 18, 2023

I didn't link to a specific commit but the feature that was added that closed this and #1419 is https://vuefire.vuejs.org/nuxt/auth.html#Session-Cookie

@MarkSonn
Copy link

thank you so much for the super fast reply!

some of the documentation was a little tricky for me to follow, so in case anyone else finds this thread i managed to get it working for my SSG app by:

  • setting GOOGLE_APPLICATION_CREDENTIALS to the service account path
  • removing sessionCookie: true from vuefire.auth in nuxt.config.ts
  • note: i didn't need to enable the IAM Service Account Credentials API or add any roles to the service account

@posva i also just wanted to explicitly make extra sure that there is no way for the service account private key to make it's way into the .output directory when using SSG where it can be seen by an unauthorised party (such as through the dev console on the frontend). if so, i know it might sound silly but could you please explicitly mention that in the docs to put the minds of people as paranoid as me at ease 😅

@Subin-Qreative
Copy link

Subin-Qreative commented Dec 7, 2023

i required sessionCookie, for some reasons it works in dev mode but fails in production / after build.
I think the culprit is my server side middleware, calls to /api/__session hits my server middleware and drops it ( intentionally , custom auth ).. I wish there was a better way to configure middleware so that they can be set on specific routes and not global ...

@Subin-Qreative
Copy link

Ok that didnt fix it ,

anyone have any ideas ?

'An internal error has occurred. Raw server response: "{"error":{"code":403,"message":"Request had insufficient authentication scopes.","errors":[{"message":"I
nsufficient Permission","domain":"global","reason":"insufficientPermissions"}],"status":"PERMISSION_DENIED","details":[{"@type":"type.googleapis.com/google.rpc.ErrorInfo","
reason":"ACCESS_TOKEN_SCOPE_INSUFFICIENT","domain":"googleapis.com","metadata":{"service":"identitytoolkit.googleapis.com","method":"google.cloud.identitytoolkit.v1.Session
ManagementService.CreateSessionCookie"}}]}}"'

@orangesnowtech
Copy link

setting ssr to true solved the problem for me!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants