Skip to content

Instantly share code, notes, and snippets.

@sanjeev-pandey23
Created July 14, 2025 13:44
Show Gist options
  • Save sanjeev-pandey23/5ea35b861e4cc64b1b0f5647feb34f73 to your computer and use it in GitHub Desktop.
Save sanjeev-pandey23/5ea35b861e4cc64b1b0f5647feb34f73 to your computer and use it in GitHub Desktop.
Google Auth Flows With Strapi User
import React, { useEffect, useState } from "react";
import { useRouter } from 'next/navigation';
// Declare google property on window object
declare global {
interface Window {
google: any;
}
}
import Script from "next/script";
import axios from "axios";
import { getAPIUrl } from "@/service/api"; // Something like `export const getAPIUrl = (path: string): string => { return BASE_URL + path; }
interface AuthProps {
fromInternalScreens: boolean;
}
const Auth = ({ fromInternalScreens }: AuthProps) => {
const [profile, setProfile] = useState(null);
const router = useRouter();
const handleLogoutSuccess = () => {
// console.log("Logging out...");
localStorage.removeItem('token');
setProfile(null);
};
/**
* User Google JWT to authenticate or register user in Strapi.
* Warning: Once you get the claims in Google JWT (@response param here),
* you still need to check that the aud claim contains one of your app's client IDs.
* If it does, then the token is both valid and intended for your client, and you
* can safely retrieve and use the user's unique Google ID from the sub claim.
* @param response
*/
const handleLoginSuccess = async (response: any) => {
const { email, name, picture, family_name, given_name } = response;
// console.log("Login flow with JWT running...", response);
try {
const res: any = await axios.get(getAPIUrl(`/api/users?filters[email]=${email}`));
// console.log("User check res", res.data);
if (res.data.length != 0) {
const res: any = await axios.post(getAPIUrl("/api/auth/local"), {
identifier: email,
password: process.env.NEXT_PUBLIC_DEFAULT_PASSWORD,
});
// console.log("Login res", res.data);
localStorage.setItem('token', res.data.jwt);
localStorage.setItem('profile', JSON.stringify(res.data.user));
setProfile(res.data.user);
fromInternalScreens ?
window.location.href = window.location.toString()
:
window.location.href = `${window.location.origin}/`;
} else {
await axios
.get('Your-Location-IP') // Optional flow
.then(async (locResponse) => {
// Strapi User Creation
const res: any = await axios.post(getAPIUrl("/api/auth/local/register"), {
email: email,
username: name,
password: process.env.NEXT_PUBLIC_DEFAULT_PASSWORD,
family_name: family_name,
given_name: given_name,
picture: picture,
city: locResponse.data.city,
zip_code: locResponse.data.zip_code,
googleToken: response,
});
localStorage.setItem('token', JSON.stringify(res.data.jwt));
setProfile(res.data.user);
localStorage.setItem('profile', JSON.stringify(profile));
fromInternalScreens ?
window.location.href = window.location.toString()
:
window.location.href = `${window.location.origin}/`;
}).catch((err) => {
console.error("Error getting location", err);
});
}
} catch (error) {
console.error('Error logging in Strapi with Google credentials', error);
}
};
const handleLoginFailure = (response: any) => {
console.error('Login failed at Google Token Auth', response);
};
const handler = async (credential: string, endpoint: string) => {
// Send request to Google to authenticate token
try {
const result = await fetch(`${endpoint}?id_token=${credential}`);
if (!result.ok) {
throw new Error("Failed to authenticate token");
}
const jwt = await result.json();
// console.log("JWT", jwt);
return jwt; // Here you can validate users from DB again if you need to
} catch (err: any) {
return err.message;
}
}
// Google will pass the login credential to this handler
const handleGoogle = async (response: any) => {
// console.log("Google response", response);
try {
const result = await handler(response.credential,
"https://oauth2.googleapis.com/tokeninfo"
);
if (result) {
handleLoginSuccess(result);
} else {
handleLoginFailure("Login failed");
}
} catch (err: any) {
console.log(`Error: ${err.message}`);
}
};
useEffect(() => {
// We check every 300ms to see if google client is loaded
const interval = setInterval(() => {
if (window.google) {
clearInterval(interval);
window.google.accounts.id.initialize({
client_id: process.env.GOOGLE_OAUTH_CLIENT_ID, // Google Client ID
callback: handleGoogle, // Handler to process login token
});
// Render the Google button
window.google.accounts.id.renderButton(
document.getElementById("google-login-btn"),
{
type: "standard",
theme: "e",
size: "large",
text: "continue_with",
shape: "rectangular",
}
);
// window.google.accounts.id.prompt(); // uncomment this line if you want auto prompt check
}
}, 300);
}, []); //eslint-disable-line
return (
<>
<Script src="https://accounts.google.com/gsi/client" async defer></Script>
</>
);
}
export default Auth;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment