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

Infinite redirection loop between SSR page & login page due to cookies #591

Closed
splacentino opened this issue Dec 8, 2022 · 3 comments
Closed

Comments

@splacentino
Copy link

splacentino commented Dec 8, 2022

  1. Have you set onVerifyTokenError and onTokenRefreshError in your config and checked for any helpful errors?

Yes, no error shown.

  1. Have you set debug: true in your config and read through server-side and client-side debug logs for any helpful messages?

Yes

  1. Have you tried the example app with your own Firebase credentials?

No.

  1. Have you read through the troubleshooting Q&A?

Yes.

Describe the bug
I am not able to run a wrapped getServerSideProps due to failure at getting user from cookies.
It then does infinite redirection between the main page and the login page.

Versions

next-firebase-auth version: 1.0.0-canary.18
Firebase JS SDK: 9.14.0
Next.js: 12.3.1

To Reproduce
Steps to reproduce the behavior:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

Expected behavior
A clear and concise description of what you expected to happen.

Debug and error logs

next-firebase-auth: [withAuthUserSSR] Calling "withAuthUserSSR" / "withAuthUserTokenSSR".
next-firebase-auth: [getUserFromCookies] Attempting to get user info from cookies via the ID token.
next-firebase-auth: [getUserFromCookies] Failed to retrieve the ID token from cookies. This will happen if the user is not logged in, the provided cookie values are invalid, or the cookie values don't align with your cookie settings. The user will be unauthenticated.

next-firebase-auth: [withAuthUserSSR] Redirecting to login.
next-firebase-auth: [withAuthUserSSR] Calling "withAuthUserSSR" / "withAuthUserTokenSSR".
next-firebase-auth: [getUserFromCookies] Attempting to get user info from cookies (not using the ID token).
next-firebase-auth: [getUserFromCookies] Successfully retrieved the user info from cookies.

next-firebase-auth: [withAuthUserSSR] Calling "withAuthUserSSR" / "withAuthUserTokenSSR".
next-firebase-auth: [getUserFromCookies] Attempting to get user info from cookies (not using the ID token).
next-firebase-auth: [getUserFromCookies] Failed to retrieve the user info from cookies. The provided cookie values might be invalid or not align with your cookie settings. The user will be unauthenticated.
next-firebase-auth: [withAuthUser] Set AuthUser to: {
  id: null,
  email: null,
  emailVerified: false,
  phoneNumber: null,
  displayName: null,
  photoURL: null,
  claims: {},
  getIdToken: [Function (anonymous)],
  clientInitialized: false,
  firebaseUser: null,
  signOut: [Function (anonymous)],
  serialize: [Function: serialize]
}
next-firebase-auth [withAuthUser] Calling "withAuthUser". [index.browser.js:2:7784](webpack://_N_E/node_modules/next-firebase-auth/build/index.browser.js?07e6)
next-firebase-auth [withAuthUser] Set AuthUser to: 
Object { id: null, email: null, emailVerified: false, phoneNumber: null, displayName: null, photoURL: null, claims: {}, getIdToken: v()
, clientInitialized: false, firebaseUser: null, … }
[index.browser.js:2:7784](webpack://_N_E/node_modules/next-firebase-auth/build/index.browser.js?07e6)
next-firebase-auth [withAuthUser] The Firebase ID token changed. New Firebase user: 
Object { providerId: "firebase", proactiveRefresh: {…}, reloadUserInfo: {…}, reloadListener: null, uid: "NpzAq...cm917wquisgYqNie63", auth: {…}, stsTokenManager: {…}, accessToken: "eyJh............NiIsImtpZCI6Ijk1MWMwOGM1MTZhZTM1MmI4OWU0ZDJlMGUxNDA5NmY3MzQ5NDJhODciLCJ0eXAiOiJKV1QifQ.eyJuYW1lIjoiU2ltb24gUGxhY2VudGlubyIsInBpY3R1cmUiOiJodHRwczovL2xoMy5nb29nbGV1c2VyY29udGVudC5jb20vYS9BRWRGVHA2RUplbzA2XzlIMFQtWEZFbm1rMlJNQUc0bDZudkswbTBwSDhHTD1zOTYtYyIsImlzcyI6Imh0dHBzOi8vc2VjdXJldG9rZW4uZ29vZ2xlLmNvbS9wZXRwcm9qZWN0Mi1lMWU4YiIsImF1ZCI6InBldHByb2plY3QyLWUxZThiIiwiYXV0aF90aW1lIjoxNjcwNTAwNjQ1LC......X2lkIjoiTnB6QXFIbGFtSWNtOTE3d3F1aXNnWXFOaWU2MyIsInN1YiI6Ik5wekFxSGxhbUljbTkxN3dxdWlzZ1lxTmllNjMiLCJpYXQiOjE2NzA1MDQ5MjcsImV4cCI6MTY3MDUwODUyNywiZW1haWwiOiJzaW1vbkBsYWItYm.....................sX3ZlcmlmaWVkIjp0cnVlLCJmaXJlYmFzZSI6eyJpZGVudGl0aWVzIjp7Imdvb2dsZS5jb20iOlsiMTExNzY1NDUxNjAxODIwNTU3MDY3Il0sImVtYWlsIjpbInNpbW9uQGxhYi1ib3guc3R1ZGlvIl19LCJzaWduX2luX3Byb3ZpZGVyIjoiZ29vZ2xlLmNvbSJ9fQ.pKyO2ERzgh_kl_sYFpGrP3MAq5l-ESw1tMReugdfzwfaSt0qJb3Jw3Yp1NBmcX1c2PpoHwBBG7VAeX_Zh6NGNhEqnPhpfqtOa9qSUUHFev6DZddPzvsVwUClGciELJhOkiiw2GuIEiE_g7brwJ2YggT7VrcUP1-oOzkTYAhxuG3K2_ZUAbdHYoHiprEnRgcpBPwxEBfrMkk8tQ9j-chbYsd5TyOR41XwD9gBJH0E1AFfPcmdn6WCXpJNTqqwe3E_PilT9dWZCtsk-IDCU1fg3s8NyzEBpihjgH7GeH2HVMSPzbTj1E48-2MdE8cCB6QxetKej-ltBidMU0zOe1w0EQ", displayName: "", email: "email@gmail.com", … }
[index.browser.js:2:7784](webpack://_N_E/node_modules/next-firebase-auth/build/index.browser.js?07e6)
next-firebase-auth [withAuthUser] Calling the login endpoint. [index.browser.js:2:7784](webpack://_N_E/node_modules/next-firebase-auth/build/index.browser.js?07e6)
next-firebase-auth [withAuthUser] Set AuthUser to: 
Object { id: "NpzAq...cm917wquisgYqNie63", email: "email@gmail.com", emailVerified: true, phoneNumber: null, displayName: "", photoURL: "http://photorul", claims: {}, getIdToken: v(e)
, clientInitialized: true, firebaseUser: {…}, … }
[index.browser.js:2:7784](webpack://_N_E/node_modules/next-firebase-auth/build/index.browser.js?07e6)
next-firebase-auth [withAuthUser] Completed the auth API request. [index.browser.js:2:7784](webpack://_N_E/node_modules/next-firebase-auth/build/index.browser.js?07e6)
next-firebase-auth [withAuthUser] Set AuthUser to: 
Object { id: "NpzAq...cm917wquisgYqNie63", email: "email@gmail.com", emailVerified: true, phoneNumber: null, displayName: "", photoURL: "http://photorul", claims: {}, getIdToken: v(e)
, clientInitialized: true, firebaseUser: {…}, … }
[index.browser.js:2:7784](webpack://_N_E/node_modules/next-firebase-auth/build/index.browser.js?07e6)
next-firebase-auth [withAuthUser] Redirecting to app. [index.browser.js:2:7784](webpack://_N_E/node_modules/next-firebase-auth/build/index.browser.js?07e6)
next-firebase-auth [withAuthUser] Calling "withAuthUser". [index.browser.js:2:7784](webpack://_N_E/node_modules/next-firebase-auth/build/index.browser.js?07e6)
next-firebase-auth [withAuthUser] Set AuthUser to: 
Object { id: "NpzAq...cm917wquisgYqNie63", email: "email@gmail.com", emailVerified: true, phoneNumber: null, displayName: "", photoURL: "http://photorul", claims: {}, getIdToken: v(e)
, clientInitialized: true, firebaseUser: {…}, … }
[index.browser.js:2:7784](webpack://_N_E/node_modules/next-firebase-auth/build/index.browser.js?07e6)
next-firebase-auth [withAuthUser] Redirecting to app. [index.browser.js:2:7784](webpack://_N_E/node_modules/next-firebase-auth/build/index.browser.js?07e6)
next-firebase-auth [withAuthUser] Set AuthUser to: 
Object { id: "NpzAq...cm917wquisgYqNie63", email: "email@gmail.com", emailVerified: true, phoneNumber: null, displayName: "", photoURL: "http://photorul", claims: {}, getIdToken: v(e)
, clientInitialized: true, firebaseUser: {…}, … }
[index.browser.js:2:7784](webpack://_N_E/node_modules/next-firebase-auth/build/index.browser.js?07e6)
next-firebase-auth [withAuthUser] Redirecting to app.

next-firebase-auth [withAuthUser] Redirecting to app. [index.browser.js:2:7784](webpack://_N_E/node_modules/next-firebase-auth/build/index.browser.js?07e6)
Too many calls to Location or History APIs within a short timeframe. [main.js:1217:42](http://localhost:4200/_next/static/chunks/main.js?ts=1670507323938%20line%20841%20%3E%20eval)
Uncaught (in promise) DOMException: The operation is insecure.

Additional context

Main page (/):

export const getServerSideProps = withAuthUserTokenSSR({
  whenUnauthed: AuthAction.REDIRECT_TO_LOGIN,

})(async ({ AuthUser, ...context }) => {
  const token = await AuthUser.getIdToken();

  console.log({ token });
  // fetch & return props
});
  
function Index(data: DataType) {
    // render page
}

export default withAuthUser<DataType>({
  whenUnauthedAfterInit: AuthAction.REDIRECT_TO_LOGIN,
})(Index);

Login page (/login):

export const Login = () => {
 return <div><FirebaseAuth /></div>
}

export const getServerSideProps = withAuthUserSSR({
  whenAuthed: AuthAction.REDIRECT_TO_APP,
})();

export default withAuthUser({
  whenAuthed: AuthAction.REDIRECT_TO_APP,
})(Login);

Custom FirebaseAuth component:

import { getApp } from 'firebase/app';
import { getAuth, GoogleAuthProvider, EmailAuthProvider, signInWithPopup } from 'firebase/auth';

export function FirebaseAuth() {
  const loginWithGoogle = async () => {
    const auth = getAuth(getApp());
    await signInWithPopup(auth, new GoogleAuthProvider());
  };

  return (
    <div>
      <button onClick={loginWithGoogle}>CLICK</button>
    </div>
  );
}

configuration:

const initAuth = () => {
  init({
    debug: process.env.NODE_ENV === 'development',

    authPageURL: '/login',
    appPageURL: '/',
    loginAPIEndpoint: '/api/auth/login', // defined + initAuth()
    logoutAPIEndpoint: '/api/auth/logout', // defined + initAuth()
    firebaseAdminInitConfig: process.env.FIREBASE_PRIVATE_KEY
      ? {
          credential: {
            projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID as string,
            clientEmail: process.env.FIREBASE_CLIENT_EMAIL as string,
            privateKey: process.env.FIREBASE_PRIVATE_KEY,
          },
          databaseURL: process.env.NEXT_PUBLIC_FIREBASE_DATABASE_URL as string,
        }
      : undefined,
    firebaseClientInitConfig: {
      apiKey: process.env.NEXT_PUBLIC_FIREBASE_PUBLIC_API_KEY as string,
      authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
      databaseURL: process.env.NEXT_PUBLIC_FIREBASE_DATABASE_URL,
      projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
    },
    onVerifyTokenError: (error) => {
      console.error('nop');
      console.error(error);
    },
    onLoginRequestError(error) {
      console.error('nop');
      console.error(error);
    },
    onTokenRefreshError: (error) => {
      console.error('nop');
      console.error(error);
    },
    cookies: {
      name: 'ProjectRelatedName',
      keys: [process.env.COOKIE_SECRET_CURRENT, process.env.COOKIE_SECRET_PREVIOUS],
      httpOnly: true,
      maxAge: TWELVE_DAYS_IN_MS,
      overwrite: true,
      path: '/',
      sameSite: 'strict',
      secure: process.env.NODE_ENV === 'production',
      signed: true,
    },
  });
};
@kmjennison
Copy link
Contributor

@splacentino Is it fixed if you use withAuthUserTokenSSR in /login rather than withAuthUserSSR? It looks like there could be a mismatch here where the ID token value in cookies isn't valid, while the user value is valid.

@splacentino
Copy link
Author

@splacentino Is it fixed if you use withAuthUserTokenSSR in /login rather than withAuthUserSSR? It looks like there could be a mismatch here where the ID token value in cookies isn't valid, while the user value is valid.

Same issue.

I reproduced the same issue (same setup) on a brand new nextjs pet project.

@splacentino
Copy link
Author

I found the issue:

got a nice non-UTF8 character in my FIREBASE_PRIVATE_KEY.

Thanks for your support

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

No branches or pull requests

2 participants