He intentado implementar la API de servicios de identidad de Google en mi aplicación React, pero no pude hacer que funcionara.
Estoy tratando de implementar el siguiente código JS realmente simple: https://developers.google.com/identity/gsi/web/guides/display-button#javascript
Lo que se me ocurrió es lo siguiente:
useEffect(() => { //I'm adding the <script> const elemScript = document.createElement('script'); elemScript.src = "https://accounts.google.com/gsi/client"; elemScript.async = true; elemScript.defer = true; document.body.append(elemScript); //adding the code from the documentation window.onload = function () { /*global google*/ console.log(google) google.accounts.id.initialize({ client_id: "<don't worry, I put the ID here>", callback: handleCredentialResponse }); google.accounts.id.renderButton( googleButton.current, //this is a ref hook to the div in the official example { theme: "outline", size: "large" } // customization attributes ); } return () => { //I get ride of the <scripts> when the elements is unmounted document.body.removeChild(elemScript); } }, []) //This is my main and only objective, to get the token... function handleCredentialResponse(response) { console.log("Encoded JWT ID token: " + response.credential); } return ( <div ref={googleButton}></div> ) } export default GoogleAuth Cuando llamo a este componente en mi aplicación principal, a veces muestra el botón, a veces no (y la causa de esto parece ser react-router-dom ya que no se cargará si me muevo de otra página en mi dominio a donde está el botón). E incluso cuando obtengo el renderizado, recibo errores y no puedo iniciar sesión.
Gracias a la respuesta de Bogdanof, se resolvió el problema del botón que solo aparecía a veces mediante el uso de Promises.
Ahora mi único problema es el siguiente:
[GSI_LOGGER]: The given origin is not allowed for the given client ID.
Creé e identifiqué OAuth2.0 en Google solo para esta aplicación. Habilité http://localhost:3000 como su origen JS (y lo mismo para los URI), pero sigo recibiendo esa respuesta. Intenté cambiar de navegador e incluso borrar mi caché y cookies mientras leía que podría ayudar, pero nada funcionó.
Alguien tiene alguna idea de como solucionar esto?
Oye, obtuve el resultado final, el siguiente código no tiene ningún problema con la representación del botón gracias al uso de Promises (nuevamente, gracias a bogdanoff por su ayuda con esto):
//External imports import { useEffect, useRef } from 'react' const loadScript = (src) => new Promise((resolve, reject) => { if (document.querySelector(`script[src="${src}"]`)) return resolve() const script = document.createElement('script') script.src = src script.onload = () => resolve() script.onerror = (err) => reject(err) document.body.appendChild(script) }) const GoogleAuth = () => { const googleButton = useRef(null); useEffect(() => { const src = 'https://accounts.google.com/gsi/client' const id = "< your ID here ;) >" loadScript(src) .then(() => { /*global google*/ console.log(google) google.accounts.id.initialize({ client_id: id, callback: handleCredentialResponse, }) google.accounts.id.renderButton( googleButton.current, { theme: 'outline', size: 'large' } ) }) .catch(console.error) return () => { const scriptTag = document.querySelector(`script[src="${src}"]`) if (scriptTag) document.body.removeChild(scriptTag) } }, []) function handleCredentialResponse(response) { console.log("Encoded JWT ID token: " + response.credential); } return ( <div ref={googleButton}></div> ) } export default GoogleAuthLuego, para resolver el problema de OAuth, encontré la solución aquí en la respuesta de Crow: el origen dado no está permitido para la ID de cliente dada (GSI)
Básicamente agregue http://localhost sin un puerto a sus orígenes (no sé por qué gsi necesita esto, pero lo necesita)
Espero que esto ayude a alguien
No he probado esto, pero he aplicado esta técnica en el pasado.
const loadScript = (src) => new Promise((resolve, reject) => { if (document.querySelector(`script[src="${src}"]`)) return resolve() const script = document.createElement('script') script.src = src script.onload = () => resolve() script.onerror = (err) => reject(err) document.body.appendChild(script) }) function GoogleAuth() { useEffect(() => { const src = 'https://accounts.google.com/gsi/client' loadScript(src) .then(() => { console.log(google) google.accounts.id.initialize({ client_id: "<don't worry, I put the ID here>", callback: handleCredentialResponse, }) google.accounts.id.renderButton( googleButton.current, //this is a ref hook to the div in the official example { theme: 'outline', size: 'large' } // customization attributes ) }) .catch(console.error) return () => { const scriptTag = document.querySelector(`script[src="${src}"]`) if (scriptTag) document.body.removeChild(scriptTag) } }, []) //This is my main and only objective, to get the token... function handleCredentialResponse(response) { console.log('Encoded JWT ID token: ' + response.credential) } return <div ref={googleButton}></div> } export default GoogleAuthpuede usar https://www.npmjs.com/package/@react-oauth/google , y puede verificar la implementación https://github.com/MomenSherif/react-oauth si desea implementar por su cuenta