Taio
Taio

Reputation: 3734

Cookie is undefined in production NextJS getServerSideProps

I am hosting my nextjs site using a custom server using a cloud function.

const { https, logger } = require("firebase-functions");
const { default: next } = require("next");

const nextjsDistDir = require("../next.config.js").distDir;
const isDev = process.env.NODE_ENV !== "production";

const nextjsServer = next({
  dev: isDev,
  conf: {
    distDir: nextjsDistDir,
  },
});
const nextjsHandle = nextjsServer.getRequestHandler();

//The `nextApp` here is the Firebase Cloud Functions name
exports.nextApp = https.onRequest((req, res) => {
  return nextjsServer.prepare().then(() => {
    logger.info(req.path, req.query);
    return nextjsHandle(req, res);
  });
});

I have an AuthProvider that is supposed to watch for changes in auth state and set a cookie containing the auth token

import nookies from 'nookies';
import firebase from "firebase/app";
import firebaseClient from "../scripts/firebaseClient";
import "firebase/auth";
import Cookies from 'js-cookie';

const AuthContext = createContext({});

export function AuthProvider({ children }) {
  firebaseClient();
  const [user, setUser] = useState(null);
  // handle auth logic here...

  // listen for token changes
  // call setUser and write new token as a cookie
  useEffect(() => {
    return firebase.auth().onIdTokenChanged(async (user) => {
      nookies.destroy(null, "token");
      if (!user) {
        setUser(null);
        console.log("no user")
        nookies.destroy(null, "token");
        //nookies.set(undefined, 'token', '', { path: '/' });
        document.cookie = `token=''; path=/`;
        // Cookies.set("token", "");
        return;
      } else {
        const token = await user.getIdToken();
        setUser(user);
        console.log("auth state token : "+token);
        nookies.destroy(null, "token");
        //console.log("auth user : "+token)
        //nookies.set(undefined, 'token', token, { path: '/' });
        // Cookies.set("token", token);
        document.cookie = `token=${token}; path=/`;
        
        
       return;
      }
    });
  }, []);

  //

  // force refresh the token every 10 minutes
  useEffect(() => {
    const handle = setInterval(async () => {
      const user = firebase.auth().currentUser;
      if (user) await user.getIdToken(true);
    }, 10 * 60 * 1000);

    // clean up setInterval
    return () => clearInterval(handle);
  }, []);

  return (
    <AuthContext.Provider value={{ user }}>{children}</AuthContext.Provider>
  );
};

export const useAuth = () => useContext(AuthContext);

I am then supposed to get the cookie in a page in getServerSideProps and check if the token contained in the cookie is valid. Only thing the cookie comes up as undefined in production. The cookie 'token' is visible in dev mode. All the other questions regarding this problem do not have a problem with the cookie in production. What could I be doing wrong. As you can see from the above code I have tried using various cookie packages to set the cookie, like nookies, next-cookies, cookies etc and they all work in dev mode and not in production

Upvotes: 1

Views: 1308

Answers (1)

jaycePark
jaycePark

Reputation: 79

https://firebase.google.com/docs/hosting/functions#using_cookies

When using Firebase Hosting together with Cloud Functions or Cloud Run, cookies are generally stripped from incoming requests. This is necessary to allow for efficient CDN cache behavior. Only the specially-named __session cookie is permitted to pass through to the execution of your app.

When present, the __session cookie is automatically made a part of the cache key, meaning that it's impossible for two users with different cookies to receive the other's cached response. Only use the __session cookie if your app serves different content depending on user authorization.

In other words, it seems that the key value of the cookie that stores the id token should be changed to "_session"

Cookies.set("__session", token);

it works well local, but when I deploy it, a problem appears. Please fix it this way and try it

Good luck.

Upvotes: 5

Related Questions