NextJs Google OAuth Integration - Alternate to Google Identify - Login using google

profile

Biswajit Nayak

4 Min Reading,

Share
12

Why Google OAuth not Google Identity?

Drawback of FedCM (Federated Credential Management) used in Google Identity

Using FedCM with Google Identity does come with some limitations that developers should be aware of. First, FedCM is currently only supported in Google Chrome, so users accessing a website from other browsers may encounter inconsistent login experiences. Additionally, FedCM does not support the more granular permissions and advanced OAuth flows available in traditional OAuth, which can limit its flexibility, especially for applications requiring high security, custom authentication flows, or access to specific user data beyond basic profile information. FedCM also lacks a well-established community and extensive documentation, making it more challenging to troubleshoot issues or find support resources. As it is backed largely by Google, using FedCM may create a dependency on Chrome-specific features, potentially impacting applications that aim to maintain a consistent experience across all browsers. For applications needing advanced authentication capabilities and cross-browser support, traditional OAuth might still be the preferable option.

Google OAuth(Non FedCM) alternate of Google Identity

Google OAuth offers a robust solution to many limitations found in FedCM, particularly around flexibility and compatibility. One major advantage is its cross-browser support; Google OAuth works seamlessly across all major browsers, including Firefox, Safari, and Edge, ensuring that users experience consistent login functionality no matter their browser choice. Furthermore, Google OAuth enables developers to request granular permissions through various scopes, allowing applications to access detailed user data like profile pictures, email addresses, and even services like Google Drive or Calendar. This flexibility is particularly valuable for applications needing data beyond basic user information. In addition, Google OAuth supports advanced authentication flows, such as the "authorization code with PKCE" flow, enhancing security for single-page and mobile applications by reducing the risks of token interception. Another benefit is its support for session management and token refreshes, which allow applications to maintain seamless, prolonged user sessions without frequent logins. Finally, Google OAuth is well-documented, widely adopted, and backed by a mature community, making it easier for developers to find resources, troubleshoot, and stay updated with best practices. These features make Google OAuth a more comprehensive and secure option for authentication, especially when compared to FedCM, which is currently limited in scope, customization, and browser compatibility.

Lets start coding!

I am using Next.js, this technique applies broadly to any JavaScript library or framework. For setting up your Google Console, refer to my article: Google Identity with Next.js 14 and Google One-Tap: From Localhost to Production – A Step-by-Step Guide. The console configuration steps are the same for both Google Identity and Google OAuth.

If you have an existing project configured with Google Identity or Google OAuth, it’s easy to switch between them. You can also use both and toggle dynamically based on browser support for FedCM (Federated Credential Management).

Assuming you have an authentication API ready, if not, you can create one by following the instructions in the guide mentioned above. The API configuration steps are reusable across Google Identity and OAuth setups.

export const openGoogleLogin = () => {
  const newNonce = Math.random().toString(36).substring(2);
  const width = 500; // Width of the popup
  const height = 600; // Height of the popup
  const screenWidth = window.innerWidth;
  const screenHeight = window.innerHeight;

  // Calculate the position to center the popup
  const top = (screenHeight - height) / 2;
  const left = (screenWidth - width) / 2;
  const googleAuthUrl = `https://accounts.google.com/o/oauth2/v2/auth?response_type=id_token&client_id=${process.env.NEXT_PUBLIC_GOOGLE_CLIENT_ID}&redirect_uri=${process.env.NEXT_PUBLIC_GOOGLE_REDIRECT_URI}&scope=openid%20profile%20email&nonce=${newNonce}`;
  window.open(
    googleAuthUrl,
    "_blank",
    `width=${width},height=${height},top=${top},left=${left}`
  );
};

This is the function to attach to your sign-in button. It initiates the login process.

<span onClick={openGoogleLohin}>Sign in</span>

Create a client page to serve as your redirect URL. Be sure to update this URL in the Google Console. Once the user confirms, Google will redirect to this page with the credential token included as a query parameter. This component will retrieve the credential token, post a message, and then our message event listener will listen for it.

import { useEffect } from "react";
import { useRouter } from "next/router";

export default function GoogleLoginPage() {
  const router = useRouter();
  useEffect(() => {
    const fragment = window.location.search;
    const params = new URLSearchParams(fragment);
    const credential = params.get("id_token"); // Get the id_token from URL
    if (credential) {
      // Send the ID token to the parent window (the one that opened the Google login window)
      window.opener.postMessage(
        { credential, loginType: "google" },
        process.env.NEXT_PUBLIC_GOOGLE_REDIRECT_URI
      );
      window.close(); // Close the popup after sending the token
    } else {
      router.push("/"); // In case the token is not available, redirect to homepage or an error page
      window.close(); // Close the popup after sending the token
    }
  }, []);

  return <div>Redirecting...</div>;
}

Next, write a message event listener.

const ref = useRef(null);
const emitMessage = async (event) => {
const response = event.data;
// change your credential name as per your auth api.
await signIn("Google", {
      credential: response.credential,
      ...nextAuthOpt,
    });
}
useEffect(() => {
    if (!ref.current) {
      window.addEventListener("message", emitMessage);
      ref.current = true;
    }

    return () => {
      window.removeEventListener("message", emitMessage);
      ref.current = null;
    };
  }, []);

Don’t forget to update your sign-in function to align with the credentials authentication API.

Happy coding!😊