awinogrodzki / next-firebase-auth-edge

Next.js Firebase Authentication for Edge and Node.js runtimes. Compatible with latest Next.js features.
https://next-firebase-auth-edge-docs.vercel.app/
MIT License
395 stars 39 forks source link

Cookie does not get set on Firebase App Hosting #188

Open gabor-s opened 1 month ago

gabor-s commented 1 month ago

We are evaluating Firebase App Hosting, but as the title says the cookie does not get set. We can see the message next-firebase-auth-edge: Updating response headers with authenticated cookies in the logs, but there's no Set-Cookie header in the response. The cookie is named __session. Locally and on Vercel it's working fine, the cookie get set.

abrahan92 commented 1 month ago

Yes, I have this issue as well. Even using the cookie: __session is not being set/cached on the response.

I've tried using the last pre-release canary version but didn't have any luck

"next-firebase-auth-edge": "^1.5.0-canary.4",

I'm running nextJS app on firebase App Hosting

return authMiddleware(request, {
    loginPath: '/api/login',
    logoutPath: '/api/logout',
    apiKey: authConfig.apiKey,
    cookieName: authConfig.cookieName,
    cookieSerializeOptions: authConfig.cookieSerializeOptions,
    cookieSignatureKeys: authConfig.cookieSignatureKeys,
    serviceAccount: authConfig.serviceAccount,
    handleValidToken: async ({ token, decodedToken }, headers) => {
      console.log('Token is valid')

      if (publicRoutes.includes(request.nextUrl.pathname)) {
        return redirectToHome(request)
      } else if (request.nextUrl.pathname === '/') {
        url.pathname = '/home'

        return NextResponse.redirect(url)
      }

      return NextResponse.next({
        request: {
          headers
        }
      })
    },
    handleInvalidToken: async reason => {
      console.info('Missing or malformed credentials', { reason })

      return redirectToLogin(request, {
        path: '/login',
        publicPaths: publicRoutes
      })
    },
    handleError: async error => {
      console.error('Unhandled authentication error', { error })

      return redirectToLogin(request, {
        path: '/login',
        publicPaths: publicRoutes
      })
    }

and this is my cookieSerializeOptions

cookieSerializeOptions: {
    path: '/',
    httpOnly: true,
    secure: process.env.NEXT_PUBLIC_USE_SECURE_COOKIES === 'true',
    sameSite: 'lax',
    maxAge: 12 * 60 * 60 * 24
  }
awinogrodzki commented 1 month ago

Hey @gabor-s, @abrahan92! Thanks for reporting

I've recently deployed latest version (1.5.0-canary.4) to Firebase Hosting environment with __session as cookie name: https://next-firebase-auth-edge-demo.web.app/ The starter example is working with no issues. I cannot seem to reproduce your issue there.

Could you provide some more context?

How do you deploy the app to Firebase App Hosting? Are you using firebase deploy from Firebase CLI?

Could you run the app in debug mode and share some logs here?

abrahan92 commented 1 month ago

Hi @awinogrodzki Thanks for taking a look

I'm deploying directly from the Firebase App Hosting, selecting a specific branch, not the Firebase CLI. But even the cloud-run server is running well, without issues. Also, I'm using the env variables from Google Secret Manager.

I have a middleware.js within my nextJS /src folder, which works locally. The thing is, on production does not set the cookie even when it is called __session

These are the production logs within the cloud-run server image

This is where I make the deployments. Firebase AppHosting deploys to Cloud Run

image

awinogrodzki commented 1 month ago

@abrahan92 thanks for the logs.

In the logs, I cannot see calls to GET /api/login endpoint. Could you open browser dev tools, go to the Network tab and copy all the details of GET /api/login request/response and share it here?

abrahan92 commented 1 month ago

@awinogrodzki This is the response from GET /api/login endpoint by the authMiddleware

image

Also, here you can see that I'm using the correct cookie __session as I get from env vars

These are Cloud Run logs

image

gabor-s commented 1 month ago

Hi @awinogrodzki We used version 1.4.5, now I tried 1.5.0-canary.4, but it's the same.

Options: image

Request/response: image

gabor-s commented 1 month ago

Firebase App Hosting and Firebase Hosting are two different beasts. For Firebase Hosting it's documented that the cookie name should be __session, but I couldn't find any information regarding Firebase App Hosting and cookies.

abrahan92 commented 1 month ago

@gabor-s Me neither; I assumed that worked similarly with Cloud Run, but it seems it doesn't

awinogrodzki commented 1 month ago

I have reproduced the issue in App Hosting environment, here: https://next-firebase-auth-edge--next-firebase-auth-edge-demo.us-central1.hosted.app/login?redirect=/

It seems App Hosting strips Set-Cookie headers from /api/login calls. I'll make some more experiments and get back to you

awinogrodzki commented 1 month ago

@abrahan92 @gabor-s

This seems like an issue with App Hosting itself.

Here's App Hosting version of the app: https://next-firebase-auth-edge--next-firebase-auth-edge-demo.us-central1.hosted.app/login?redirect=/

And here's the same instance, accessed by Cloud Run url directly: https://next-firebase-auth-edge-m2gwdqnpta-uc.a.run.app/

When you open Dev Tools > Network tab to analyze requests, you can see that in Cloud Run environment we have following headers attached to each request:

Set-Cookie:
X-Test-Cookie=test-value; Max-Age=1036800; Path=/; HttpOnly; Secure; SameSite=Lax
Set-Cookie:
X-Test-Cookie-2=test-value-2

When you use App Hosting url, Set-Cookie headers are stripped by envoy client.

I cannot find a way to overwrite this behaviour in App Hosting settings. This is a good candidate to report to Google team

abrahan92 commented 1 month ago

Hey @awinogrodzki

Having spent more than five days testing and even creating a combination of your library and cloud functions, I won't be able to fix that behavior. That's what I feared.

It's worth reporting it to them. I will

The first one to be served can come and let us know.

Thanks both

gabor-s commented 1 month ago

Thanks @awinogrodzki , I opened a Firebase bug report, I'll let you know when they respond.

minhdanh commented 1 week ago

Hi @gabor-s, did you have this fixed?

gabor-s commented 1 week ago

Hi @minhdanh , nope, their "engineering team is still discussing" the issue.

gabor-s commented 6 days ago

I've just found this in Firebase App Hosting Known issues and limitations:

Set-Cookie headers are stripped from responses served through the App Hosting dataplane. A fix will be available in a later release.