react-google-login icon indicating copy to clipboard operation
react-google-login copied to clipboard

How to execute the onSuccess callback when using "redirect" in "uxMode"

Open foncyc opened this issue 6 years ago • 9 comments

Hi, how do I make the onSuccess callback execute if I'm using "redirect" in "uxMode" ? I'm trying to put user info in sessionStorage and it works fine if I use the popup version but it returns null when I use redirect.

Please help. I'm still new to ReactJS.

    const responseOk = (response) => {
            var profile = response.getBasicProfile();
            console.log(profile);
            sessionStorage.setItem('profile', profile);
            this.props.history.push('/');
    }

    const responseFailed = (response) => {
            console.log('Sign-in Failed');
            console.log(response);
    }

    <GoogleLogin
                clientId="key"
                buttonText="Sign in with Google"
                onSuccess={responseOk}
                onFailure={responseFailed}
                uxMode='redirect'
                redirectUri='http://localhost:3000'
    />

foncyc avatar Mar 29 '18 13:03 foncyc

I think the onSuccess callback won't work in redirect mode. As you navigate away from the page, the callback won't be invoked when you get back to the page.

Maybe you can solve this, if you register a listener for the users sign-in state: https://developers.google.com/identity/sign-in/web/reference Once the user is signed in you can get more information about the user / profile directly from the gapi.

mactanner avatar Apr 20 '18 12:04 mactanner

Got the same issue but it does make sense. As on the redirect my component is being unmounted so there is no way to get a hold the response. It would be good if there was a way to make it wait for the response and pass it to the next view.

csalmeida avatar Jun 22 '18 09:06 csalmeida

If you add isSignedIn or isSignedIn={true} then the onSuccess/onFailure callbacks are called on load which is helpful for redirect and for when a user is already signed in

ArrayKnight avatar Aug 22 '19 21:08 ArrayKnight

If you add isSignedIn or isSignedIn={true} then the onSuccess/onFailure callbacks are called on load which is helpful for redirect and for when a user is already signed in

Hello I am currently fighting this, I have tried even this and the callback wont ever trigger.... Well no, it does trigger once, then you logout, and no matter what you do, it wont trigger ever again

MortimerMarsyja avatar Feb 11 '21 14:02 MortimerMarsyja

If you add isSignedIn or isSignedIn={true} then the onSuccess/onFailure callbacks are called on load which is helpful for redirect and for when a user is already signed in

This worked for me one time, then when I logged out, it never triggered again

MortimerMarsyja avatar Feb 16 '21 09:02 MortimerMarsyja

Hi, so is listening for the code on the URL the only option for uxMode="redirect"? Thanks!

sidharrth2002 avatar Aug 14 '21 13:08 sidharrth2002

I think the onSuccess callback won't work in redirect mode. As you navigate away from the page, the callback won't be invoked when you get back to the page.

Maybe you can solve this, if you register a listener for the users sign-in state: https://developers.google.com/identity/sign-in/web/reference Once the user is signed in you can get more information about the user / profile directly from the gapi.

@mactanner How to listen to this users sign-in state?

Shofol avatar Nov 03 '21 11:11 Shofol

Hi all, I came up with a temporary fix. The component unmounts the minute you leave the page through a redirect and hence, the callback doesn't trigger (or occasionally does in an unstable manner). Instead of switching to a separate auth service, you can send the redirect to a different route that manually listens for changes in the URL through a useEffect, grabs the code, authenticates the user into the app (in my case, I get a JWT from my backend and set it in Redux) and redirects to your homepage.

I wrote a simple GoogleLandingPage component that handles this flow, as shown below.

import React, { useEffect } from "react";
import axios from "axios";
import { useDispatch } from "react-redux";
import { LOGIN } from "../../features/counter/authSlice";
import { useToast } from "@chakra-ui/react";
import { useHistory } from "react-router-dom";

const GoogleLanding = () => {
  const dispatch = useDispatch();
  const toast = useToast();
  const history = useHistory();

  useEffect(() => {
    let currentURL = window.location.href;
    console.log(currentURL);
    const params = new URLSearchParams(currentURL);
    // parse the id token from the URL
    const idToken = params.get("id_token");
    if (idToken !== null) {
      // sending to backend to get back JWT
      axios
        .post(`${process.env.REACT_APP_API_URL}auth/google`, {
          token: idToken,
        })
        .then((res) => {
          if (res.status === 201) {
            dispatch(LOGIN(res.data));
            history.push("/home");
          }
        })
        .catch((err) => {
          console.log(err);
          toast({
            title: "Failed to Load",
            description: "Something went wrong on our side!",
            status: "error",
            duration: 10,
            isClosable: false,
            position: "top",
          });
        });
    } else {
      console.log("no token");
    }
  }, [history]);
  return <div>Google Landing Page</div>;
};

export default GoogleLanding;

sidharrth2002 avatar Dec 30 '21 07:12 sidharrth2002

Hi all, I came up with a temporary fix. The component unmounts the minute you leave the page through a redirect and hence, the callback doesn't trigger (or occasionally does in an unstable manner). Instead of switching to a separate auth service, you can send the redirect to a different route that manually listens for changes in the URL through a useEffect, grabs the code, authenticates the user into the app (in my case, I get a JWT from my backend and set it in Redux) and redirects to your homepage.

I wrote a simple GoogleLandingPage component that handles this flow, as shown below.

import React, { useEffect } from "react";
import axios from "axios";
import { useDispatch } from "react-redux";
import { LOGIN } from "../../features/counter/authSlice";
import { useToast } from "@chakra-ui/react";
import { useHistory } from "react-router-dom";

const GoogleLanding = () => {
  const dispatch = useDispatch();
  const toast = useToast();
  const history = useHistory();

  useEffect(() => {
    let currentURL = window.location.href;
    console.log(currentURL);
    const params = new URLSearchParams(currentURL);
    // parse the id token from the URL
    const idToken = params.get("id_token");
    if (idToken !== null) {
      // sending to backend to get back JWT
      axios
        .post(`${process.env.REACT_APP_API_URL}auth/google`, {
          token: idToken,
        })
        .then((res) => {
          if (res.status === 201) {
            dispatch(LOGIN(res.data));
            history.push("/home");
          }
        })
        .catch((err) => {
          console.log(err);
          toast({
            title: "Failed to Load",
            description: "Something went wrong on our side!",
            status: "error",
            duration: 10,
            isClosable: false,
            position: "top",
          });
        });
    } else {
      console.log("no token");
    }
  }, [history]);
  return <div>Google Landing Page</div>;
};

export default GoogleLanding;

Thank you for this. I am doing a similar thing, except I get the response "incorrect value" when switching using id_token. Access token was working, but now I switched to uxMode="redirect" so that the login would work inside in-app browsers.

Do you know how to fix "incorrect value" when passing id_token from the URL parameter?

brandonbyr4 avatar May 02 '22 05:05 brandonbyr4