Reputation: 3734
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
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