deepakaggarwal7/react-social-login

Unhandled error using google authentication (Deprecated libraries)

nonils opened this issue ยท 11 comments

Hello all, I am getting this error using the social login and google authentication.
It's not rendering.
If you use and older integration it's rendering, but I have issues with the new integration

Error: [google][load] Failed to load SDK

ORIGINAL ERROR: {
"error": "idpiframe_initialization_failed",
"details": "You have created a new client application that uses libraries for user authentication or authorization that will soon be deprecated. New clients must use the new libraries instead; existing clients must also migrate before these libraries are deprecated. See the Migration Guide for more information."
}
at rslError (social-login.js:196:1)
at social-login.js:3398:1
at e.Np (cb=gapi.loaded_0?le=scs:242:25)
at ak (cb=gapi.loaded_0?le=scs:245:245)
at Wj (cb=gapi.loaded_0?le=scs:245:96)
at _.Aj.uw (cb=gapi.loaded_0?le=scs:244:244)
at yj (cb=gapi.loaded_0?le=scs:237:284)

I'm getting the same error

@deepakaggarwal7 At the moment to create a new integration using a new client id and client secret it's broking. I dont remember the error, but is not releated to the March 2023 google deprecation. I used the same client to different app (Using a backend server) and it's working. So, I think that the problem is releated to javascript origin (But let me check and I will try to update more details)

skuro commented

just checking, is the update to this library still on track to be released before March 31 2023, when Google will deprecate the "legacy" authentication method?

Is there an update on this?

Any updates on this?

Plan to work it coming weekend. will post update

Please let me know if there is anything I can do to help @deepakaggarwal7

I went through the migration guide
https://developers.google.com/identity/gsi/web/guides/migration

Almost all methods used like SignIn(), IsAutenticated(), getProfile() etc. do not exist anymore and the onus is more on the application itself to manage full state (which was otherwise handled by Google SDK).

In google.js file of our project, following is the starting point of change (code updated using the new library)

js.src = 'https://accounts.google.com/gsi/client'
  js.id = 'gapi-client'

  js.onload = () => {
    const client = google.accounts.oauth2.initTokenClient({
      client_id: appId,
      scope: scope,
      callback: (response) => {
       console.log(response)
      },
    });

    window.gapiClient = client;
    resolve()
  }
 

I'm exploring if the pieces can be somehow be stitched back. Now, we'd need to store the token for persistence somewhere. what could be a safe place for that?

I request you guys also give a shot and share opinions. thanks

Since this hasn't been addressed for several months and the deprecation deadline is approachign quickly, I just switched to @react-oauth/google for Google authentication with jwt_decode to decode the JWT token response.

Here's an example component:

import React, { useRef, useState } from 'react';
import { GoogleLogin } from '@react-oauth/google';
import jwt_decode from 'jwt-decode';

import SocialButton from './SocialButton';
import { FacebookLoginButton } from 'react-social-login-buttons';

const SocialLogin = () => {
  const [user, setUser] = useState(null);

  const refs = {
    facebook: useRef(null),
  };

  const logout = () => {
    if (user) {
      if (user._provider !== 'google') {
        refs[user._provider].current.logout();
      }
      setUser(null);
    }
  };

  const handleSocialLoginFailure = err => {
    console.error(err);
  };

const handleGoogleLogin = credentialResponse => {
  const decoded = jwt_decode(credentialResponse.credential);
  const user = {
    _profile: {
      email: decoded.email,
      firstName: decoded.given_name,
      lastName: decoded.family_name,
      profilePicURL: decoded.picture,
      fullName: `${decoded.given_name} ${decoded.family_name}`,
    },
    _provider: 'google',
  };
  setUser(user);
};

  const avatar =
    (user && user._profile.profilePicURL) ||
    'https://maxcdn.icons8.com/Share/icon/p1em/users/gender_neutral_user1600.png';

  return (
    <>
      {user && (
        <>
          <div><img src={avatar} alt="avatar" /></div>
          <div>Logged in as: {user._profile.fullName}</div>
          <div onClick={logout}>Log out</div>
        </>
      )}

      <SocialButton
        provider="facebook"
        appId={process.env.REACT_APP_FACEBOOK_OAUTH_APP_ID}
        onLoginSuccess={u => setUser(u)}
        onLoginFailure={handleSocialLoginFailure}
        ref={refs['facebook']}
      >
        <FacebookLoginButton
          style={{
            width: '220px',
            margin: '0',
            fontSize: '12px',
            fontWeight: 'bold',
            height: '40px',
            display: user ? 'none' : 'block'
          }}
        >
          <span>Continue with Facebook</span>
        </FacebookLoginButton>
      </SocialButton>

      {!user && (
        <GoogleLogin
          onSuccess={credentialResponse => {
            handleGoogleLogin(credentialResponse);
          }}
          onError={() => {
            handleSocialLoginFailure('login failed');
          }}
          style={{ width: '100%' }}
          text="continue_with"
          shape="rectangle"
          useOneTap={true}
          width={220}
        />
      )}
    </>
  );
};

export default SocialLogin;

This would need to be inside a <GoogleOAuthProvider /> somewhere in one of the parent components.