-1

I make a React and Sanity project.

But can't authentication with Google. How solve this secure way? (and not with "chewing gum")

I get the following message: Uncaught TypeError: Cannot destructure property 'name' of 'response.profileObj' as it is undefined.

This cause i don't get profileObj and therefore can't destruct the name property also...

Instead i get this object:

{
    "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](https://developers.google.com/identity/gsi/web/guides/gis-migration) for more information."
}

Login.js

import React from 'react';
import GoogleLogin from 'react-google-login';
import { useNavigate } from 'react-router-dom';
import { FcGoogle } from 'react-icons/fc';
import shareVideo from '../assets/share.mp4';
import logo from '../assets/logowhite.png';

import { client } from '../client';

const Login = () => {
  const navigate = useNavigate();
  const responseGoogle = (response) => {
      console.log(response)
    localStorage.setItem('user', JSON.stringify(response.profileObj));
    const { name, googleId, imageUrl } = response.profileObj;
    const doc = {
      _id: googleId,
      _type: 'user',
      userName: name,
      image: imageUrl,
    };
    client.createIfNotExists(doc).then(() => {
      navigate('/', { replace: true });
    });
  };

  return (
    <div className="flex justify-start items-center flex-col h-screen">
      <div className=" relative w-full h-full">
        <video
          src={shareVideo}
          type="video/mp4"
          loop
          controls={false}
          muted
          autoPlay
          className="w-full h-full object-cover"
        />

        <div className="absolute flex flex-col justify-center items-center top-0 right-0 left-0 bottom-0    bg-blackOverlay">
          <div className="p-5">
            <img src={logo} width="130px" />
          </div>

          <div className="shadow-2xl">
            <GoogleLogin
              clientId={`${process.env.REACT_APP_GOOGLE_API_TOKEN}`}
              render={(renderProps) => (
                <button
                  type="button"
                  className="bg-mainColor flex justify-center items-center p-3 rounded-lg cursor-pointer outline-none"
                  onClick={renderProps.onClick}
                  disabled={renderProps.disabled}
                >
                  <FcGoogle className="mr-4" /> Sign in with google
                </button>
              )}
              onSuccess={responseGoogle}
              onFailure={responseGoogle}
              cookiePolicy="single_host_origin"
            />
          </div>
        </div>
      </div>
    </div>
  );
};

export default Login;

package.json

{
  "name": "xxxx",
  "private": true,
  "version": "1.0.0",
  "description": "xxxx",
  "main": "package.json",
  "author": "xxxx",
  "license": "UNLICENSED",
  "scripts": {
    "start": "sanity start",
    "build": "sanity build"
  },
  "keywords": [
    "sanity"
  ],
  "dependencies": {
    "@sanity/base": "^2.34.0",
    "@sanity/core": "^2.34.0",
    "@sanity/default-layout": "^2.34.0",
    "@sanity/default-login": "^2.34.0",
    "@sanity/desk-tool": "^2.34.1",
    "@sanity/eslint-config-studio": "^2.0.0",
    "@sanity/vision": "^2.34.0",
    "eslint": "^8.6.0",
    "prop-types": "^15.7",
    "react": "^17.0",
    "react-dom": "^17.0",
    "styled-components": "^5.2.0"
  },
  "devDependencies": {}
}

Milán Nikolics
  • 503
  • 2
  • 5
  • 23

3 Answers3

3

You need to decode the JWT token. It is inside the 'credential' property of the response. Simply install the jwt-decode package: npm i jwt-decode

Then import it and use it in Login.jsx:

import jwt_decode from 'jwt-decode';

const USER = 'pint-clone-user';

// use jwt_decode()
 const responseGoogle = (response) => {
    console.log(response);
    localStorage.setItem(USER, JSON.stringify(response.credential));

    const { name, jti, picture } = jwt_decode(response.credential); // here
    console.log({ name, jti, picture });

    // save user as a Sanity 'user' document
    const doc = {
      _id: jti,               // here
      _type: 'user',
      userName: name,
      image: picture,    // here
    };

    client.createIfNotExists(doc).then(() => {
      navigate('/', { replace: true });
    });
  };  
1

I'm doing the same project here and it got the same error. Maybe this project is not available anymore due this restriction of the libraries.

Some one found out vulnerabilities on NPM, i think id should be a motif to they block the access of npm to google cloud, now that its public

1

its because google have updated there policies. you should try this out . but before doing it make sure to install google latest auth npm, and JWT decoded

const Login = () => {
    const navigate = useNavigate();


      const createorGetUser = (response) => {
        const decoded : { name: string, picture: string, sub: string}=jwt_decode(response.credential);
             const {name, picture, sub}= decoded;
              console.log(decoded);

              const user = {
                _id: sub,
                _type: 'user',
                userName: name,
                image: picture,
              };

                             

        client.createIfNotExists(user).then(() => {
          navigate('/', { replace: true });
        });
      };



  return (
    <div className="flex justify-start items-center flex-col h-screen">

      <div className="relative w-full h-full">
        {/* video */}
        <video
          src={shareVideo}
          type="video/mp4"
          loop
          controls={false}
          muted
          autoPlay
          className="w-full h-full object-cover"
        />

        {/* Black overlay */}

        <div className="absolute flex flex-col justify-center items-center top-0 right-0 left-0 bottom-0 bg-blackOverlay  ">

          {/* logo pic */}

          <div className="p-5">
            <img src={logo} width="130px" alt="logo" />
          </div>

          {/* Google login */}

          <div className="shadow-2xl">

            <GoogleLogin
              onSuccess={(createorGetUser)}

              onError={() => {
                console.log('Error');
              }}
            />


          </div>
        </div>

      </div>

    </div>
  )
}

export default Login;