Issue
Forgive me...I am a Python developer trying to integrate a Google OAuth flow into a react/TypeScript frontend. I have based this from examples from the react-oauth
docs. What I want to do is dynamically generate the state
token to be passed to useGoogleLogin
when the login button is clicked.
const googleLogin = useGoogleLogin({
ux_mode: "redirect",
state: "token", // <= I want to dynamically set this value when the login button is clicked
redirect_uri: "http://localhost:3000/auth/google/callback/",
flow: "auth-code",
scope: "https://www.googleapis.com/auth/drive.readonly",
onSuccess: (codeResponse) => console.log('Login OK so far'),
onError: (error) => console.log('Login Failed:', error)
});
this is called in the page like so:
<button onClick={() => googleLogin()}>Sign in with Googlefo 🚀 </button>
I can't figure out a way around the "rules of hooks" and and how to wrap this useGoogleLogin
, but it seems like this should be an easy thing to accomplish. I have a method that I can call that requests a state token from the backend and can be called like this: const token = await api.user.getStateToken()
. This token is temporarily cached on the back end so I would like to retrieve it synchronously when the login button is clicked.
This is what I do for LinkedIn login, which is hand-coded to initiate the OAuth redirect but simple enough and should give an idea of what I am looking for.
const onLoginLinkedIn = async () => {
// need the request to the backend for a state token to resolve before moving on.
// the state token is used to verify that the later callback from LinkedIn is
// related to this call
const token = await api.user.getStateToken()
await router.push(`https://www.linkedin.com/oauth/v2/authorization?response_type=code&client_id=${client_id}&redirect_uri=${encodeURIComponent(callback_uri)}&state=${token}&scope=r_basicprofile%20r_emailaddress%20w_member_social`)
}
this is called on the page like so:
<img src="./linkedin/Sign-in-Large---Default.png" alt={"Login LinkedIn"} onClick={onLoginLinkedIn}/>
Is there a way to can create something equivalent to this, but that uses useGoogleLogin
instead of the router.push
?
Solution
The useGoogleLogin
returns a function that you can execute when needed. The returned function is updated when state
changes.
Your login should update the state
, and when state
is updated, a useEffect
should trigger and perform the actual login call:
const [state, setState] = useState<string | undefined>();
const googleLogin = useGoogleLogin({
ux_mode: "redirect",
state,
redirect_uri: "http://localhost:3000/auth/google/callback/",
flow: "auth-code",
scope: "https://www.googleapis.com/auth/drive.readonly",
onSuccess: (codeResponse) => console.log('Login OK so far'),
onError: (error) => console.log('Login Failed:', error)
});
useEffect(() => {
if(state) googleLogin(state); // call googleLogin when state is defined
}, [googleLogin, state]);
const onLogin = async() => {
const token = await api.user.getStateToken()
setState(token)
};
Answered By - Ori Drori
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.