Skip to content

Instantly share code, notes, and snippets.

@ovarunendra
Created April 24, 2023 01:31
Show Gist options
  • Save ovarunendra/ff7a420cf76d6c5bb3bb1fc695c8f561 to your computer and use it in GitHub Desktop.
Save ovarunendra/ff7a420cf76d6c5bb3bb1fc695c8f561 to your computer and use it in GitHub Desktop.
PKCE flow with a ReactJS
import React, { useEffect } from 'react';
import { login, logout, handleRedirectCallback, getToken } from './auth';
const App = () => {
useEffect(() => {
handleRedirectCallback();
}, []);
const handleLogin = async () => {
await login();
};
const handleLogout = () => {
logout();
};
const handleGetToken = async () => {
const token = await getToken();
console.log(token);
};
return (
<div>
<button onClick={handleLogin}>Login</button>
<button onClick={handleLogout}>Logout</button>
<button onClick={handleGetToken}>Get Token</button>
</div>
);
};
export default App;
import createAuth0Client from '@auth0/auth0-spa-js';
const auth0Config = {
domain: 'YOUR_AUTH0_DOMAIN',
client_id: 'YOUR_AUTH0_CLIENT_ID',
redirect_uri: window.location.origin,
audience: 'YOUR_AUTH0_AUDIENCE',
};
let auth0Client = null;
export const createClient = async () => {
auth0Client = await createAuth0Client({
...auth0Config,
useRefreshTokens: true,
cacheLocation: 'localstorage',
});
};
export const login = async () => {
const codeVerifier = generateCodeVerifier();
const codeChallenge = await generateCodeChallenge(codeVerifier);
const loginOptions = {
code_challenge: codeChallenge,
code_challenge_method: 'S256',
};
await auth0Client.loginWithRedirect(loginOptions);
};
export const logout = () => {
auth0Client.logout({
returnTo: window.location.origin,
});
};
export const handleRedirectCallback = async () => {
const { appState } = await auth0Client.handleRedirectCallback();
navigate(appState && appState.targetUrl ? appState.targetUrl : window.location.pathname);
};
export const getToken = async () => {
if (!auth0Client) {
await createClient();
}
const token = await auth0Client.getTokenSilently();
return token;
};
const generateCodeVerifier = () => {
const array = new Uint32Array(56 / 2);
window.crypto.getRandomValues(array);
return encode(array);
};
const encode = (data) => {
const base64 = btoa(String.fromCharCode.apply(null, data));
return base64
.replace(/=/g, '')
.replace(/\+/g, '-')
.replace(/\//g, '_');
};
const generateCodeChallenge = async (codeVerifier) => {
const buffer = new TextEncoder().encode(codeVerifier);
const digest = await crypto.subtle.digest('SHA-256', buffer);
const hash = encode(new Uint8Array(digest));
return hash;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment