我做了一个React和Sanity项目。
但无法通过谷歌进行身份验证。如何解决这种安全的方式?(而不是用"口香糖"(
我得到以下消息:未捕获类型错误:无法销毁"response.profileObj"的属性"name",因为它未定义
这是因为我没有得到profileObj,因此也不能破坏name属性。。。
相反,我得到了这个对象:
{
"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;
软件包.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": {}
}
您需要解码JWT令牌。它在响应的"credential"属性内。只需安装jwt解码包:npm i jwt解码
然后导入并在Login.jsx:中使用
从"jwt解码"导入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 });
});
};
我在这里做同样的项目,但它得到了同样的错误。也许由于库的限制,这个项目已经不可用了。
有人发现了NPM上的漏洞,我认为id应该是他们阻止NPM访问谷歌云的一个主题,现在它公开了😕
这是因为谷歌已经更新了那里的政策。你应该试试这个。但在做之前,请确保安装谷歌最新的auth-npm,并由JWT解码
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;