1. Preparation

You have to create a Project on the google cloud console and within the authentification settings of the projects you need to create an “OAuth-Client-ID”

For “Authorized JS Source” you may put http://localhost:4000 and for “authrorized callback url” http://localhost:4000/oauth/google/callback this has to be the same url that is passed to the OAuth library as callback url, if they dont match you get an error. Changing this URL might take a few minutes to a few hours so dont be impatient

If we created the Authentification we can add the following to the env.

GOOGLE_CLIENT_ID=client id
GOOGLE_CLIENT_SECRET=secret

2. Installing packages

first we need to install following packages:

npm i express-session jsonwebtoken connect-mongo passport-oauth2

3. Server.ts

Now we can modify the server.ts. Add the following two endpoints to our express server.

import passport from "passport";
import session from "express-session";
import jwt from "jsonwebtoken";
import getCookieExpiration from 'payload/dist/utilities/getCookieExpiration'
import MongoStore from 'connect-mongo'
import GoogleOAuthStrategy from './authStrategies/GoogleOAuthStrategy';

// this is called to initialize the auth processs
app.get("/oauth2/authorize", passport.authenticate("googleOauth"));

// this is the callback called by google and here we need to initialize the session for our user with the jwt
app.get(
  "/oauth/google/callback",
  // Initialize session middleware with configuration options
  session({
    resave: false,  // Prevents resaving session if not modified
    saveUninitialized: false,  // Prevents saving uninitialized sessions
    secret: process.env.PAYLOAD_SECRET || 'default_secret', // Secret for signing the session ID cookie
    store: process.env.MONGODB_URI ? MongoStore.create({ mongoUrl: process.env.MONGODB_URI }) : undefined, // Session store configuration
  }),

  // Passport middleware to handle OAuth2 authentication
  passport.authenticate("googleOauth", { failureRedirect: "/login" }),

  // Callback function executed after successful authentication
  function (req, res) {
    // Access configuration for the 'users' collection
    const collectionConfig = payload.collections["users"].config;
    
    // Select the fields from the user object to include in the JWT
    let fieldsToSign = {
      email: req.user.email,  // User's email
      id: req.user.id,  // User's ID
      collection: "users",  // Collection to which the user belongs
    };

    // Sign the JWT with selected fields
    const token = jwt.sign(fieldsToSign, payload.secret, {
      expiresIn: collectionConfig.auth.tokenExpiration,  // Set token expiration as per configuration
    });

    // Set a cookie in the response with the JWT
    res.cookie(`${payload.config.cookiePrefix}-token`, token, {
      path: "/",  // Cookie path
      httpOnly: true,  // HttpOnly flag for security
      expires: getCookieExpiration(collectionConfig.auth.tokenExpiration),  // Cookie expiration time
      secure: collectionConfig.auth.cookies.secure,  // Secure flag (for HTTPS)
      sameSite: collectionConfig.auth.cookies.sameSite,  // SameSite attribute
      domain: collectionConfig.auth.cookies.domain || undefined,  // Cookie domain
    });

    // Redirect user to the admin dashboard after successful authentication
    res.redirect("/admin");
  }
);

For your own frontend change the redirect

// Redirect user to the main page after successful authentication
res.redirect("<http://localhost:3000/>");

Add the following to the start function after the


// Configure Passport with Google OAuth Strategy
passport.use("googleOauth",GoogleOAuthStrategy);

// Serialize the user to the session
// Only the user ID is stored in the session for efficiency.
passport.serializeUser((user, done) => {
  done(null, user.id);
});

// Deserialize the user from the session
// This is used to retrieve the full user information based on the stored ID.
passport.deserializeUser(async (id, done) => {
  try {
    const user = await payload.findByID({ collection: "users", id });
    done(null, user);
  } catch (error) {
    done(error);
  }
});

4. Auth Button (server backend auth)

Add the following component to the project

import React from 'react';
import Button from 'payload/dist/admin/components/elements/Button';

/**
 * GoogleLogin Component
 * Renders a button for initiating OAuth2 Google Login.
 * The url has to be the same as the passport.authenticate... call
 * in the server.ts
 */
export default function GoogleLoginButton() {
  return (
    <div>
      <Button el="anchor" url="/oauth2/authorize">
        Login with Google
      </Button>
    </div>
  );
}

5. payload.config.ts (server backend auth)