Skip to content

Instantly share code, notes, and snippets.

@h-sakano
Last active April 16, 2020 06:45
Show Gist options
  • Save h-sakano/9e8fe7757afafaed4d1a6d29be3e49b5 to your computer and use it in GitHub Desktop.
Save h-sakano/9e8fe7757afafaed4d1a6d29be3e49b5 to your computer and use it in GitHub Desktop.
auth0-spa-js(https://github.com/auth0/auth0-spa-js) with TypeScript
import createAuth0Client, {
Auth0Client,
Auth0ClientOptions,
GetIdTokenClaimsOptions,
GetTokenSilentlyOptions,
GetTokenWithPopupOptions,
IdToken,
LogoutOptions,
PopupConfigOptions,
PopupLoginOptions,
RedirectLoginOptions,
RedirectLoginResult,
} from '@auth0/auth0-spa-js';
import React, { useState, useEffect } from 'react';
const DEFAULT_REDIRECT_CALLBACK = () =>
window.history.replaceState({}, document.title, window.location.pathname);
interface Auth0ContextValue {
getIdTokenClaims?: (
options?: GetIdTokenClaimsOptions,
) => Promise<IdToken> | undefined;
getTokenSilently?: (
options?: GetTokenSilentlyOptions,
) => Promise<any> | undefined;
getTokenWithPopup?: (
options?: GetTokenWithPopupOptions,
config?: PopupConfigOptions,
) => Promise<string> | undefined;
handleRedirectCallback?: (
url?: string,
) => Promise<RedirectLoginResult | undefined>;
isAuthenticated: boolean;
loading: boolean;
loginWithPopup?: (
options?: PopupLoginOptions,
config?: PopupConfigOptions,
) => Promise<void>;
loginWithRedirect?: (
options?: RedirectLoginOptions,
) => Promise<void> | undefined;
logout?: (options?: LogoutOptions) => void;
popupOpen: boolean;
user?: any;
}
export const Auth0Context = React.createContext<Auth0ContextValue>({
isAuthenticated: false,
loading: false,
popupOpen: false,
});
interface Auth0ProviderProps extends Auth0ClientOptions {
children: React.ReactNode;
onRedirectCallback?: (appState?: any) => void;
}
export const Auth0Provider: React.FC<Auth0ProviderProps> = ({
children,
onRedirectCallback = DEFAULT_REDIRECT_CALLBACK,
...initOptions
}) => {
const [isAuthenticated, setIsAuthenticated] = useState(false);
const [user, setUser] = useState<any>();
const [auth0Client, setAuth0] = useState<Auth0Client>();
const [loading, setLoading] = useState(true);
const [popupOpen, setPopupOpen] = useState(false);
useEffect(() => {
const initAuth0 = async () => {
const auth0FromHook = await createAuth0Client(initOptions);
setAuth0(auth0FromHook);
if (
window.location.search.includes('code=') &&
window.location.search.includes('state=')
) {
const { appState } = await auth0FromHook.handleRedirectCallback();
onRedirectCallback(appState);
}
const authenticated = await auth0FromHook.isAuthenticated();
setIsAuthenticated(authenticated);
if (authenticated) {
const u = await auth0FromHook.getUser();
setUser(u);
}
setLoading(false);
};
initAuth0();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const loginWithPopup = async (
options?: PopupLoginOptions,
config?: PopupConfigOptions,
) => {
setPopupOpen(true);
try {
await auth0Client?.loginWithPopup(options, config);
} catch (error) {
// eslint-disable-next-line no-console
console.error(error);
} finally {
setPopupOpen(false);
}
const u = await auth0Client?.getUser();
setUser(u);
setIsAuthenticated(true);
};
const handleRedirectCallback = async (url?: string) => {
setLoading(true);
const redirectResult = await auth0Client?.handleRedirectCallback(url);
const u = await auth0Client?.getUser();
setUser(u);
setLoading(false);
setIsAuthenticated(true);
return redirectResult;
};
return (
<Auth0Context.Provider
value={{
getIdTokenClaims: (options?: GetIdTokenClaimsOptions) =>
auth0Client?.getIdTokenClaims(options),
getTokenSilently: (options?: GetTokenSilentlyOptions) =>
auth0Client?.getTokenSilently(options),
getTokenWithPopup: (
options?: GetTokenWithPopupOptions,
config?: PopupConfigOptions,
) => auth0Client?.getTokenWithPopup(options, config),
handleRedirectCallback,
isAuthenticated,
loading,
loginWithPopup,
loginWithRedirect: (options?: RedirectLoginOptions) =>
auth0Client?.loginWithRedirect(options),
logout: (options?: LogoutOptions) => auth0Client?.logout(options),
popupOpen,
token,
user,
}}
>
{children}
</Auth0Context.Provider>
);
};
import { useContext } from 'react';
import { Auth0Context } from 'contexts/auth0';
export const useAuth0 = () => useContext(Auth0Context);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment