auth0-spa-js: Next js login @auth0/auth0-spa-js not working with loginWithRedirect while loginWithPopup works well

Problem

When trying to use loginWithRedirect using https://github.com/auth0/auth0-spa-js first time it successfully logging me in and takes to onboard page means window.location.origin after login when I’m trying to login next time it just reloads the page and taking me back again and again while loginWithPopup works well.

What was the expected behavior?

Expected behaviour is after login it should take me to dashboard with token & user details.

Reproduction

Environment

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 2
  • Comments: 24 (9 by maintainers)

Most upvoted comments

I don’t think we’ve changed anything specific in this area that would be causing your issue, but I’ve yet to deep-dive into it. Once I’ve had a chance to try and reproduce it this week, I’ll come back to you.

@tiwarivijay123 I’ve got some feedback on your code sample I can share tomorrow.

@TrueWill we also have an SDK built specially for Next.js in case that’s an even better fit: https://github.com/auth0/nextjs-auth0

Yeah ok thanks @stevehobbsdev I guess now you can close this issue

Here is more code to review @stevehobbsdev , any issues here please let us know…

function AuthProvider({ children }: AuthProviderProps) {
  const [open, setOpen] = useState(true);
  const router = useRouter();
  const [state, dispatch] = useReducer(reducer, initialState);
  const [isRegister, setIsRegister] = useState(false);
  async function getUserInfo(user: any, isAuthenticated: any) {
    try {
      const response = await axios.get('user/?filter={"where":{"email":"' + user.email + '"}}');
      console.log(response.data[0], 'user info');
      if (response.data.length == 0) {
        router.push({
          pathname: PATH_AFTER_SIGNUP,
          query: { returnUrl: router.asPath },
        });
      } else {
        return response.data[0];
      }
    } catch (error) {
      dispatch({
        type: Types.init,
        payload: { isAuthenticated: false, user: null },
      });
    }
  }

  const handleClickOpen = () => {
    setOpen(true);
  };

  const handleClose = () => {
    setOpen(false);
  };
  const Transition = forwardRef(function Transition(
    props: TransitionProps & {
      children: React.ReactElement<any, any>;
    },
    ref: React.Ref<unknown>
  ) {
    return <Slide direction="up" ref={ref} {...props} />;
  });
  useEffect(() => {
    console.log(AUTH0_API.clientId, AUTH0_API.domain, 'Domain');
    const initialize = async () => {
      try {
        auth0 = new Auth0Client({
          client_id: '',
          domain: '',
          redirect_uri: window.location.origin,
          audience: '',
        });

        await auth0.checkSession();

        const isAuthenticated = await auth0.isAuthenticated();

        if (isAuthenticated) {
          const user = await auth0.getUser();
          const userInfo = await getUserInfo(user, isAuthenticated);
          // dispatch({
          //   type: Types.init,
          //   payload: { isAuthenticated, user: userInfo || null },
          // });
        } else {
          dispatch({
            type: Types.init,
            payload: { isAuthenticated, user: null },
          });
        }
      } catch (err) {
        console.error(err, 'erorr');
        dispatch({
          type: Types.init,
          payload: { isAuthenticated: false, user: null },
        });
      }
    };

    initialize();
  }, []);
  const login = async () => {
    try {
      await auth0?.loginWithRedirect();
    } catch (error) {
      let res = error.error_description.split(':');
      console.log(res[1], 'res 1');
      setIsRegister(true);
      return res;
    }
    if (isRegister == false) {
      const isAuthenticated = await auth0?.isAuthenticated();
      const user = await auth0.getUser();
      console.log(user, isAuthenticated, 'auth response');
      if (isAuthenticated) {
        const user = await auth0?.getUser();
        const accessToken = await auth0.getTokenSilently();
        axios.defaults.baseURL = '';
        axios.defaults.headers.common['Authorization'] = `Bearer ${accessToken}`;
        axios.interceptors.request.use(
          (request) => {
            console.log(request);
            // Edit request config
            return request;
          },
          (error) => {
            console.log(error);
            return Promise.reject(error);
          }
        );

        axios.interceptors.response.use(
          (response) => {
            console.log(response);
            // Edit response config
            return response;
          },
          (error) => {
            console.log(error);
            return Promise.reject(error);
          }
        );
        const userInfo = await getUserInfo(user, isAuthenticated);
        localStorage.setItem('userId', userInfo.id);
        localStorage.setItem('accessToken', accessToken);
        dispatch({ type: Types.login, payload: { user: userInfo || null } });
      } else {
      }
    } else {
      const isAuthenticated = await auth0?.isAuthenticated();
      const user = await auth0.getUser();
      console.log(user, isAuthenticated, 'auth response');
      if (isAuthenticated) {
        const user = await auth0?.getUser();
        const accessToken = await auth0.getTokenSilently();
        localStorage.setItem('signupEmail', user?.email);
        window.localStorage.setItem('accessToken', accessToken);

        axios.defaults.baseURL = '';
        axios.defaults.headers.common['Authorization'] = `Bearer ${accessToken}`;
        axios.interceptors.request.use(
          (request) => {
            console.log(request);
            // Edit request config
            return request;
          },
          (error) => {
            console.log(error);
            return Promise.reject(error);
          }
        );
        axios.interceptors.response.use(
          (response) => {
            console.log(response);
            // Edit response config
            return response;
          },
          (error) => {
            console.log(error);
            return Promise.reject(error);
          }
        );
      }
      // setIsRegister(false);
      router.push({
        pathname: PATH_AFTER_SIGNUP,
        query: { returnUrl: router.asPath },
      });
      // dispatch({ type: Types.Register, payload: { user: user } });
    }
  };

  const logout = () => {
    auth0?.logout();
    dispatch({ type: Types.logout });
  };
  console.log(state, 'state');

  return (
    <AuthContext.Provider
      value={{
        ...state,
        method: 'auth0',
        user: {
          additionalInfo: state?.user,
          id: state?.user?.sub,
          photoURL: state?.user?.avatar_signed_url,
          email: state?.user?.email,
          displayName: state?.user?.contact?.fullname,
          role: state?.user?.contact?.header,
        },
        login,
        logout,
      }}
    >
      {children}
    </AuthContext.Provider>
  );
}

@tiwarivijay123 in your code sample, you can’t simply await loginWithRedirect and expect a result, as it will do a full-page redirect and state is lost. You need to call handleRedirectCallback when Auth0 redirects back to your application in order to get authentication results.

I tried it’s older version as well https://github.com/auth0/auth0-spa-js/releases but nothing seem to work. after successfully login it just come to back with undefined user detail and does nothing I’m using this version its latest but I tried older version as well but it is same Screenshot 2022-03-29 at 10 57 41 AM this is code which I’m trying for loginWithRedirect Screenshot 2022-03-29 at 10 59 57 AM Screenshot 2022-03-29 at 10 54 06 AM

I just saw something similar - unsure if it’s the same bug or not.

We upgraded from version 1.10.0 to 1.20.1, so I would not expect any breaking changes (assuming people follow semver). I didn’t see anything impactful in the changelog.

But now when calling loginWithRedirect (identical code other than the library version) and passing a redirect_uri, it’s redirecting to a different URL and resulting in a 404.

Using more-or-less vanilla JS on this project (Backbone). Browser Chrome.