Search code examples
javascriptreactjsgoogle-identitygoogle-one-tap

Google Identity Services Login with React


I'm trying to implement Google Identity Services Login without third parties, everything works well because I get the response when I try to sign in, except for the error shown in the console:

"Failed to load resource: the server responded with a status of 401 ()"

This is my code:

useEffect(() => {
    try {
      google.accounts.id.initialize({
        client_id:
          "CODE.apps.googleusercontent.com",
        callback: handleCallbackResponse,
      });

      google.accounts.id.renderButton(document.getElementById("buttonDiv"), {
        theme: "outline",
        size: "large",
        text: "continue_with",
      });

      window.google.accounts.id.prompt();
    } catch (e) {
      alert("Error", e);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);


function handleCallbackResponse(response) {
    //code
  }

return (<div id="buttonDiv"></div>)

Solution

  • Your code only handles authentication (who is the user) and you should handle authorization (what is the user) as well in order to grant user access to server resources.

    Response error with status code 401 tells that you are unauthorized. That means you have to get an access token and use it in your HTTP requests' headers. For that, you can use initTokenClient like in the following example:

    const client = google.accounts.oauth2.initTokenClient({
      client_id: <YOUR_CLIENT_ID>,
      scope: <YOUR_SCOPES>, // these are defined in Google Cloud console within enabled APIs
      hint: '[email protected]',
      callback: (tokenResponse) => {
        // store access token in cookie
      }
    })
    
    client.requestAccessToken({ prompt: '', hint: '[email protected]' })
    

    The best way to do this is to wrap it in a function and call it on user event (e.g., click). Otherwise, browsers' default settings usually block popups and redirects which may produce UX issues.