Skip to content

sun-labs/cloudgarden-passwordless-react-example-with-pkce

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Cloudgarden passwordless login react example (with pkce)

For a example on how to request a code/link, see:

function PasswordlessLoginRequestCodePage() {
let navigate = useNavigate();
const { requestLoginCode, loading } = usePasswordless(REDIRECT_URI, CLIENT_ID)
async function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
event.preventDefault();
let formData = new FormData(event.currentTarget)
let email = formData.get("email") as string
await requestLoginCode(email)
navigate('/claim')
}
if (loading) return <p>Loading...</p>
return (
<div>
<form onSubmit={handleSubmit}>
<label>
Email: <input name="email" type="email" />
</label>
<button type="submit">Send code</button>
</form>
</div>
);
}
and
const requestLoginCode = async (email: string, clientId?: string, redirectUri?: string): Promise<void> => {
setLoading(true)
const codeVerifier = generateCodeVerifier()
const codeChallengeMethod = 'sha256'
const codeChallenge = await generateCodechallenge(codeVerifier)
await fetch(`${BASE_ENDPOINT}/auth/passwordlessLogin/code`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
credentials: 'same-origin',
body: JSON.stringify({
email,
client_id: clientId || clientIdDefault,
redirect_uri: redirectUri || redirectUriDefault,
code_challenge_method: codeChallengeMethod,
code_challenge: codeChallenge
})
})
setCodeVerifier(codeVerifier)
setLoading(false)
}

For a example on how to use the code/link, see:

function PasswordlessLoginClaimCodePage() {
const { code } = useQuery()
const [tokens, setTokens] = React.useState()
const { claimLoginCode, loading } = usePasswordless(REDIRECT_URI, CLIENT_ID)
async function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
event.preventDefault();
let formData = new FormData(event.currentTarget);
let code = formData.get("code") as string;
const res = await claimLoginCode(code)
setTokens(res)
}
const tokenEffectFn = async () => {
if (!code) return
const res = await claimLoginCode(code)
setTokens(res)
}
// @ts-expect-error 2345
React.useEffect(tokenEffectFn, [code])
if (loading) return <p>Loading...</p>
return (
<div>
{code && !tokens && (
<p>Your code is: {code}</p>
)}
{!code && !tokens && (
<form>
<label>
Code: <input name="code" type="text" />
</label>
<button type="submit">Claim code</button>
</form>
)}
{tokens && (
<pre>{JSON.stringify(tokens, null, 2)}</pre>
)}
</div>
)
}
and
const claimLoginCode = async (code: string, clientId?: string, redirectUri?: string): Promise<any> => {
setLoading(true)
const codeVerifier = getCodeVerifier()
const response = await fetch(`${BASE_ENDPOINT}/auth/oauth2/token`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
credentials: 'same-origin',
body: JSON.stringify({
grant_type: 'authorization_code',
code,
code_verifier: codeVerifier,
client_id: clientId || clientIdDefault,
redirect_uri: redirectUri || redirectUriDefault,
})
})
const tokens = await response.json()
setLoading(false)
return tokens
}

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published