Created
July 14, 2025 13:44
-
-
Save sanjeev-pandey23/5ea35b861e4cc64b1b0f5647feb34f73 to your computer and use it in GitHub Desktop.
Google Auth Flows With Strapi User
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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