{"id":75768,"date":"2024-09-05T07:18:01","date_gmt":"2024-09-05T03:48:01","guid":{"rendered":"https:\/\/nabfollower.com\/blog\/google-login-oauth-error401-in-react-frontend-5e10\/"},"modified":"2024-09-05T07:18:01","modified_gmt":"2024-09-05T03:48:01","slug":"google-login-oauth-error401-in-react-frontend-5e10","status":"publish","type":"post","link":"https:\/\/nabfollower.com\/blog\/google-login-oauth-error401-in-react-frontend-5e10\/","title":{"rendered":"\u062e\u0637\u0627\u06cc Google Login OAuth: 401 \u062f\u0631 React Frontend"},"content":{"rendered":"<p>Summarize this content to 400 words in Persian Lang <\/p>\n<p>![Image description](https:\/\/dev-to-uploads.s3.amazonaws.com\/uploads\/articles\/cflrqbnar8aef26t7lv3.png)Login.jsx<br \/>\nimport{ useState } from &#8220;react&#8221;;<br \/>\nimport { GoogleOAuthProvider, GoogleLogin } from &#8220;@react-oauth\/google&#8221;;<br \/>\nimport { FaFacebook, FaLinkedin } from &#8220;react-icons\/fa&#8221;;<br \/>\nimport { Link, useNavigate } from &#8220;react-router-dom&#8221;;<br \/>\nimport { facebookLogin, linkedinLogin } from &#8220;..\/..\/utils\/api&#8221;;<br \/>\nimport logo from &#8220;..\/..\/assets\/logo.png&#8221;; \/\/ Ensure the correct path to your logo<\/p>\n<p>const clientId = &#8220;xxxx&#8221;; \/\/ Replace with your actual Google client ID<\/p>\n<p>const Login = () =&gt; {<br \/>\n  const [error, setError] = useState(&#8220;&#8221;);<br \/>\n  const navigate = useNavigate();<\/p>\n<p>  const handleGoogleSuccess = async (credentialResponse) =&gt; {<br \/>\n    try {<br \/>\n      const token = credentialResponse.credential;<\/p>\n<p>      \/\/ Fetch user profile info from Google<br \/>\n      \/\/const userInfoResponse = await fetch(`https:\/\/www.googleapis.com\/oauth2\/v3\/userinfo?access_token=${token}`, {<br \/>\n      const userInfoResponse = await fetch(`https:\/\/www.googleapis.com\/oauth2\/v3\/userinfo?token=${token}`);<br \/>\n      if (!userInfoResponse.ok) {<br \/>\n        throw new Error(`Failed to fetch user info: ${userInfoResponse.statusText}`);<br \/>\n      }<br \/>\n      const userInfo = await userInfoResponse.json();<br \/>\n      console.log(&#8220;User info:&#8221;, userInfo);<\/p>\n<p>      \/\/ Send user info to the backend<br \/>\n      const response = await fetch(&#8220;http:\/\/localhost:3000\/auth\/gxxxxx&#8221;, {<br \/>\n        method: &#8220;POST&#8221;,<br \/>\n        headers: {<br \/>\n          &#8220;Content-Type&#8221;: &#8220;application\/json&#8221;,<br \/>\n        },<br \/>\n        body: JSON.stringify({<br \/>\n          firstName: userInfo.given_name || &#8220;&#8221;,<br \/>\n          lastName: userInfo.family_name || &#8220;&#8221;,<br \/>\n          email: userInfo.email || &#8220;&#8221;,<br \/>\n        }),<br \/>\n      });<\/p>\n<p>      if (!response.ok) {<br \/>\n        throw new Error(`Backend responded with status: ${response.status}`);<br \/>\n      }<\/p>\n<p>      const data = await response.json();<br \/>\n      console.log(&#8220;Backend response:&#8221;, data);<\/p>\n<p>      if (data.token) {<br \/>\n        localStorage.setItem(&#8220;token&#8221;, data.token);<br \/>\n        navigate(&#8220;https:\/\/dev.to\/&#8221;);<br \/>\n      } else {<br \/>\n        setError(data.message || &#8220;Google login failed&#8221;);<br \/>\n      }<br \/>\n    } catch (err) {<br \/>\n      setError(err.message || &#8220;An error occurred during Google login&#8221;);<br \/>\n    }<br \/>\n  };<\/p>\n<p>  const handleGoogleFailure = () =&gt; {<br \/>\n    setError(&#8220;Google login failed. Please try again.&#8221;);<br \/>\n  };<\/p>\n<p>  return (<\/p>\n<p>Login<\/p>\n<p>          {error &amp;&amp; {error}}<\/p>\n<p> Sign in with Facebook<\/p>\n<p> Sign in with LinkedIn<\/p>\n<p>Dont have an account? <\/p>\n<p>              Create one<\/p>\n<p>  );<br \/>\n};<\/p>\n<p>export default Login;<\/p>\n<p>    \u0648\u0627\u0631\u062f \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0634\u0648\u06cc\u062f<\/p>\n<p>    \u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/p>\n<p>\u0633\u0644\u0627\u0645 \u062a\u06cc\u0645Front End: React.js. \u0648\u0631\u0648\u062f \u0628\u0647 \u0633\u06cc\u0633\u062a\u0645 Google OAuthBackend: Express API Endpoint\u0647\u0631 \u06af\u0648\u0646\u0647 \u067e\u06cc\u0634\u0646\u0647\u0627\u062f \u06cc\u0627 \u0628\u0627\u0632\u062e\u0648\u0631\u062f \u0627\u0633\u062a\u0642\u0628\u0627\u0644 \u0645\u06cc \u0634\u0648\u062f. \u067e\u06cc\u0634\u0627\u067e\u06cc\u0634 \u0645\u0645\u0646\u0648\u0646<\/p>\n<div data-article-id=\"1987445\" id=\"article-body\">\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight plaintext\"><code>![Image description](https:\/\/dev-to-uploads.s3.amazonaws.com\/uploads\/articles\/cflrqbnar8aef26t7lv3.png)Login.jsx\nimport{ useState } from \"react\";\nimport { GoogleOAuthProvider, GoogleLogin } from \"@react-oauth\/google\";\nimport { FaFacebook, FaLinkedin } from \"react-icons\/fa\";\nimport { Link, useNavigate } from \"react-router-dom\";\nimport { facebookLogin, linkedinLogin } from \"..\/..\/utils\/api\";\nimport logo from \"..\/..\/assets\/logo.png\"; \/\/ Ensure the correct path to your logo\n\nconst clientId = \"xxxx\"; \/\/ Replace with your actual Google client ID\n\nconst Login = () =&gt; {\n  const [error, setError] = useState(\"\");\n  const navigate = useNavigate();\n\n  const handleGoogleSuccess = async (credentialResponse) =&gt; {\n    try {\n      const token = credentialResponse.credential;\n\n      \/\/ Fetch user profile info from Google\n      \/\/const userInfoResponse = await fetch(`https:\/\/www.googleapis.com\/oauth2\/v3\/userinfo?access_token=${token}`, {\n      const userInfoResponse = await fetch(`https:\/\/www.googleapis.com\/oauth2\/v3\/userinfo?token=${token}`);\n      if (!userInfoResponse.ok) {\n        throw new Error(`Failed to fetch user info: ${userInfoResponse.statusText}`);\n      }\n      const userInfo = await userInfoResponse.json();\n      console.log(\"User info:\", userInfo);\n\n      \/\/ Send user info to the backend\n      const response = await fetch(\"http:\/\/localhost:3000\/auth\/gxxxxx\", {\n        method: \"POST\",\n        headers: {\n          \"Content-Type\": \"application\/json\",\n        },\n        body: JSON.stringify({\n          firstName: userInfo.given_name || \"\",\n          lastName: userInfo.family_name || \"\",\n          email: userInfo.email || \"\",\n        }),\n      });\n\n      if (!response.ok) {\n        throw new Error(`Backend responded with status: ${response.status}`);\n      }\n\n      const data = await response.json();\n      console.log(\"Backend response:\", data);\n\n      if (data.token) {\n        localStorage.setItem(\"token\", data.token);\n        navigate(\"https:\/\/dev.to\/\");\n      } else {\n        setError(data.message || \"Google login failed\");\n      }\n    } catch (err) {\n      setError(err.message || \"An error occurred during Google login\");\n    }\n  };\n\n  const handleGoogleFailure = () =&gt; {\n    setError(\"Google login failed. Please try again.\");\n  };\n\n  return (\n<googleoauthprovider clientid=\"{clientId}\">\n<div classname=\"flex flex-col items-center justify-center min-h-screen bg-gray-100\">\n<div classname=\"w-full max-w-md p-8 bg-white rounded shadow\">\n\n<h2 classname=\"mb-4 text-2xl text-center\">Login<\/h2>\n\n          {error &amp;&amp; <p classname=\"mb-4 text-sm text-red-500\">{error}<\/p>}\n<p>\n<button onclick=\"{facebookLogin}\" classname=\"flex items-center justify-center w-full p-2 mb-2 text-white bg-blue-700 rounded hover:bg-blue-800\">\n<fafacebook classname=\"mr-2\"\/> Sign in with Facebook\n<\/button>\n<button onclick=\"{linkedinLogin}\" classname=\"flex items-center justify-center w-full p-2 text-white bg-blue-600 rounded hover:bg-blue-700\">\n<falinkedin classname=\"mr-2\"\/> Sign in with LinkedIn\n<\/button>\n<\/p>\n\n<p>\n<span>Dont have an account? <\/span>\n<link to=\"\/register\" classname=\"text-blue-500 hover:underline\"\/>\n              Create one\n\n<\/p>\n<\/div>\n<\/div>\n<\/googleoauthprovider>\n  );\n};\n\nexport default Login;\n\n\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\">\n    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"><title>\u0648\u0627\u0631\u062f \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"\/>\n<\/svg><\/p>\n<p>    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"><title>\u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"\/>\n<\/svg><\/p>\n<\/div>\n<\/div>\n<\/div>\n<p>\u0633\u0644\u0627\u0645 \u062a\u06cc\u0645<br \/>Front End: React.js. \u0648\u0631\u0648\u062f \u0628\u0647 \u0633\u06cc\u0633\u062a\u0645 Google OAuth<br \/>Backend: Express API Endpoint<br \/>\u0647\u0631 \u06af\u0648\u0646\u0647 \u067e\u06cc\u0634\u0646\u0647\u0627\u062f \u06cc\u0627 \u0628\u0627\u0632\u062e\u0648\u0631\u062f \u0627\u0633\u062a\u0642\u0628\u0627\u0644 \u0645\u06cc \u0634\u0648\u062f. \u067e\u06cc\u0634\u0627\u067e\u06cc\u0634 \u0645\u0645\u0646\u0648\u0646<\/p>\n<\/p><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Summarize this content to 400 words in Persian Lang ![Image description](https:\/\/dev-to-uploads.s3.amazonaws.com\/uploads\/articles\/cflrqbnar8aef26t7lv3.png)Login.jsx import{ useState } from &#8220;react&#8221;; import { GoogleOAuthProvider, GoogleLogin } from &#8220;@react-oauth\/google&#8221;; import { FaFacebook, FaLinkedin } from &#8220;react-icons\/fa&#8221;; import { Link, useNavigate } from &#8220;react-router-dom&#8221;; import { facebookLogin, linkedinLogin } from &#8220;..\/..\/utils\/api&#8221;; import logo from &#8220;..\/..\/assets\/logo.png&#8221;; \/\/ Ensure the correct path to your &hellip;<\/p>\n","protected":false},"author":2,"featured_media":75769,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"fifu_image_url":"","fifu_image_alt":"","footnotes":""},"categories":[339],"tags":[],"class_list":["post-75768","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dev"],"_links":{"self":[{"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/posts\/75768","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/comments?post=75768"}],"version-history":[{"count":0,"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/posts\/75768\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/media\/75769"}],"wp:attachment":[{"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/media?parent=75768"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/categories?post=75768"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/tags?post=75768"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}