Cookie 在生产 NextJS getServerSideProps 中未定义

Tai*_*aio 1 cookies next.js

我使用云功能的自定义服务器托管我的 nextjs 网站。

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);
  });
});
Run Code Online (Sandbox Code Playgroud)

我有一个 AuthProvider 应该监视身份验证状态的变化并设置一个包含身份验证令牌的 cookie

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);
Run Code Online (Sandbox Code Playgroud)

然后我应该获取页面中的 cookiegetServerSideProps并检查 cookie 中包含的令牌是否有效。唯一的事情是 cookie 在生产中出现undefined。cookie“令牌”在开发模式下可见。关于此问题的所有其他问题都与生产中的 cookie 没有问题。我可能做错了什么。正如您从上面的代码中看到的,我尝试使用各种 cookie 包来设置 cookie,例如、nookies等,它们都在开发模式下工作,而不是在生产模式下工作next-cookiescookies

小智 5

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

当 Firebase Hosting 与 Cloud Functions 或 Cloud Run 一起使用时,通常会从传入请求中删除 cookie。这是实现高效 CDN 缓存行为所必需的。仅允许特别命名的 __session cookie 传递到您的应用程序的执行。

如果存在,__session cookie 会自动成为缓存键的一部分,这意味着具有不同 cookie 的两个用户不可能接收对方的缓存响应。仅当您的应用程序根据用户授权提供不同的内容时,才使用 __session cookie。

也就是说,存储id token的cookie的键值似乎应该改为“_session”

Cookies.set("__session", token);
Run Code Online (Sandbox Code Playgroud)

它在本地运行良好,但是当我部署它时,出现问题。请按此方法修复并尝试

祝你好运。