无法解构“response.profileObj”的属性“name”,因为它未定义

问题描述 投票:0回答:12
const navigate = useNavigate();

  const responseGoogle = (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 });
    });
  };

我收到“名称未定义”的错误 – 但怎么办?

imageUrl
googleId
工作正常,那么
name
有什么问题吗?

reactjs google-api google-authentication
12个回答
3
投票

我猜你和我一样正在从事 (https://www.youtube.com/watch?v=XxXyfkrP298&t=3800s) 的 ShareMe 项目。

登录已更新,现在 Google 服务在响应中返回一组与录制视频时返回的参数不同的参数。

您正在寻找的参数(例如“name”和“id”)现在可以在response.credential中找到,但它已被编码(出于安全原因),现在您必须对其进行解码。您必须使用“npm i jwt-decode”() 在“shareme_frontend”文件夹中安装“jwt-decode”,并且您将能够使用“var generatedHeader = jwt_decode(response.credential);”对其进行解码,您应该能够使用属性“名称”、“子”(而不是 ID)和“图片”,这应该可以帮助您加快速度。

您遇到的问题是名称未定义,因为没有response.name,只有response.credential.name并且需要解码。因此,这可能会非常令人沮丧,但当您打印回复时您会看到问题。

来源:

我的例子:

import jwt_decode from "jwt-decode";


const responseGoogle=(response)=>{
    localStorage.setItem('user', JSON.stringify(response.profileObj));
    var decodedHeader = jwt_decode(response.credential);
    console.log(decodedHeader);

    const { name, sub, picture } = decodedHeader;

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

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

  }


0
投票

这可能是一个符号问题,请尝试这个:

const navigate = useNavigate();

const responseGoogle = (response) => {

localStorage.setItem('user', JSON.stringify(response.profileObj));

const doc = {
  _id: response.profileObj.googleId,
  _type: 'user',
  userName: response.profileObj.name,
  image: response.profileObj.imageUrl,
};

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

};


0
投票

更新:React 更新了他们的登录方法,所以你需要搜索最新的 google 登录方法


0
投票

尝试添加

npm install gapi-script

然后像这样添加useEffect函数

useEffect(() => {
function start() {
  gapi.client.init({
    ClientId: process.env.REACT_APP_GOOGLE_API_TOKEN,
    scope: '',
  })
}
gapi.load('client:auth2', start)})

0
投票

我遇到了同样的问题,同样的问题,这是shareme项目吗?我认为 googleId 和 imageUrl 也不起作用。您可以像这样切换这三个的顺序

const {  imageUrl,name, googleId } = response.profileObj;

它会给你错误: cb=gapi.loaded_0?le=scs:225 未捕获类型错误:无法解构“response.profileObj”的属性“imageUrl”,因为它未定义。

所以我也卡在这里寻求帮助!


0
投票

这个问题已经过去很长时间了,但我找到了一个对我有用的解决方案,我以这种方式对呼叫进行了更改

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

我还更改了谷歌按钮库,使用了@react-oauth/google,按钮看起来像这样:

<GoogleLogin
   onSuccess={responseGoogle}
   onError={responseGoogle}/>

0
投票

我已经解决这个问题有一段时间了,结果发现同一件事有不同的方法。(React 不断更新谷歌登录方法,因此需要更新的方法), 在响应对象中存在凭证属性,它需要通过 jwt_decode 函数进行解码,该函数可以从库“jwt-decode”中导入,可以进一步提取详细信息。

const responseGoogle = (response) =>{
    console.log(response);
    var profileObj = jwt_decode(response.credential);
    console.log(profileObj);
    const doc = {
      _id: profileObj.sub,
      _type: "user",
      userName: profileObj.name,
      image: profileObj.picture,
      };
    client.createIfNotExists(doc)
      .then(()=>{
        console.log('Login Created')
      });  

0
投票

代码应该如下所示:

import jwt_decode from "jwt-decode";    

const responseGoogle = (response) =>{
    console.log(response);
    var profileObj = jwt_decode(response.credential);
    console.log(profileObj);
    const doc = {
        _id: profileObj.sub,
        _type: "user",
        userName: profileObj.name,
        image: profileObj.picture
    };

    console.log(doc)
    client.createIfNotExists(doc)
          .then(()=>{
              navigate("/", { replace: true });
              console.log('Login Created')
          }); 
} 

0
投票

有新更新,我们使用 Google Identity Services SDK 检查此链接 https://www.npmjs.com/package/@react-oauth/google .

尝试使用此代码登录并获取用户信息。

登录.jsx:

import React from 'react'
import { GoogleOAuthProvider } from '@react-oauth/google';
import { GoogleLogin, googleLogout } from '@react-oauth/google';
import { useNavigate } from 'react-router-dom';
import {FcGoogle} from 'react-icons/fc' ;
import shareVideo from '../assets/share.mp4' ;
import logo from '../assets/mejlis-logo.png' ;
import {client} from '../client';
import jwt_decode  from "jwt-decode";
//import JWT from 'google-auth-library';
const Login = () => {
  const navigate = useNavigate();
  const responseGoogle = async(response) => {
    localStorage.setItem('user', JSON.stringify(response));
    console.log(response);
    const decoded = jwt_decode(response.credential)
    const { sub, name, picture } = decoded;
    const doc = {
      _id: sub,
      _type: 'user',
      userName: name,
      image: picture,
    };
    client.createIfNotExists(doc).then(() => {
      navigate('/', { replace: true });
    });
  };
  
  return (
    <div className='flex justify-start items-center flex-col h-screen'>
      <div className='relativr w-full h-full'>
        <video src ={shareVideo} type ='video/mp4'
        loop
        controls={false}
        muted
        autoPlay
        className='w-full h-full object-cover' />
      </div>
      <div className='absolute flex flex-col justify-center items-center top-0 right- left-0 bottom-0 bg-blackOverlay'>
        <div className='p=5'>
          <img  src={logo} width="130px" alt='logo'/>
        </div>
        <div className='shadow-2x1'>
          <GoogleOAuthProvider
          clientId={`${process.env.REACT_APP_GOOGLE_API_TOKEN}`}>
            <GoogleLogin
            onSuccess={responseGoogle}
            onFailure={responseGoogle}
            cookiePolicy = 'single_host_origin' />
          </GoogleOAuthProvider>

        </div>
      </div>
    </div>
  )
}
export default Login

0
投票

为谷歌创建的问题更新了他们的谷歌登录设置。您可以在安装最新的 Google OAuth 后尝试此代码:

const navigate = useNavigate();
    
const responseGoogle = (response) => {
  const decoded = jwt_decode(response.credential);
  console.log(decoded);
    
  const { name, picture, sub } = decoded;
    
  const user = {
    _id: sub,
    _type: 'user',
    userName: name,
    image: picture
  };

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

0
投票

正如许多人在我之前指出的那样,发生此错误的原因不仅是由于 Google 新响应中的结构不同,而且还因为教程视频中建议的用于 Google Login 的 React 库已被弃用。这是解决问题的最新方法:

首先,更新您用于 Google 登录的库。为此,请在终端中运行:

npm uninstall react-google-login

然后,安装当前最新的库React OAuth2 |谷歌。按照其 npm 页面上的步骤(请参阅前面的链接)安装此库。在本教程的特定情况下,步骤如下:

(1)安装新库

npm install @react-oauth/google@latest

(2) 使用 GoogleOAuthProvider 包装您的应用程序。你的 App.js 文件应该看起来像这样:

import React from "react";
import { Routes, Route, useNavigate } from "react-router-dom";
import { GoogleOAuthProvider } from "@react-oauth/google";
import Login from "./components/Login";
import Home from "./container/Home";

const App = () => {
  return (
    <GoogleOAuthProvider clientId={process.env.REACT_APP_GOOGLE_API_TOKEN}>
      <Routes>
        <Route path="login" element={<Login />} />
        <Route path="/*" element={<Home />} />
      </Routes>
    </GoogleOAuthProvider>
  );
};

export default App;

(3) 更改 Login.jsx 文件中的代码,以反映所用库的更改和响应结构的更改。它应该看起来有点像这样:

import { GoogleLogin } from "@react-oauth/google";
const responseGoogle = (response) => {
 localStorage.setItem("user", JSON.stringify(response.profileObj));
 const decodedHeader = jwt_decode(response.credential);
 
 const { name, sub, picture } = decodedHeader;
 const doc = {
   _id: sub,
   _type: "user",
   userName: name,
   image: picture,
 };
 
 client.createIfNotExists(doc).then(() => {
   navigate("/", { replace: true });
 });
};

对于响应或所使用的库的未来更改,请尝试控制台记录 Google 响应本身。就我而言,这些错误非常准确地告诉我如何修复错误。


0
投票

我注意到使用“aud”无法正常工作。相反,使用 sub 来正确传递不同的 googleID。

这是我的源代码至少。

    import React from 'react'
// import GoogleLogin from 'react-google-login'
import { GoogleOAuthProvider } from '@react-oauth/google';
import { GoogleLogin, googleLogout } from '@react-oauth/google'
import jwt_decode from 'jwt-decode';
import { useNavigate } from 'react-router-dom'
import shareVideo from '../assets/share.mp4'
import logo from '../assets/LogoSWhite2.png'

import {client} from '../client'


const Login = () => {

    // const responseGoogle = (response) => {
    //     console.log(response);
    //   }
    const navigate = useNavigate();

    const responseGoogle = (response) => {
      const decode = jwt_decode(response.credential);
      console.log(decode);
        localStorage.setItem('user', JSON.stringify(decode));
        const { name, sub, picture } = decode;

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

        console.log("googleId:", sub);
        console.log("image:", picture);



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

  return (
    <div className="flex justiy-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" alt="logo" />
        </div>

        <div className='shadow-2xl'>
        <GoogleOAuthProvider clientId={process.env.REACT_APP_GOOGLE_API_TOKEN}>
          <GoogleLogin
            onSuccess={responseGoogle}
            onFailure={responseGoogle}
            cookiePolicy="single_host_origin"
          />
        </GoogleOAuthProvider>


            {/* <GoogleOAuthProvider
             clientId={process.env.REACT_APP_GOOGLE_API_TOKEN}>
              <GoogleLogin
             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"
            
            />;
            </GoogleOAuthProvider>; */}
            


        </div>

        </div>
      </div>
    </div>
  )
}

export default Login
© www.soinside.com 2019 - 2024. All rights reserved.