OpenID Connect (OIDC) and OAuth2 protocol support for React Single Page Applications (SPA).
Using npm
npm install @developertown/oidc-providerUsing yarn
yarn add @developertown/oidc-provider@developertown/oidc-provider provides a simplified api for integrating Auth0. The simplified api is nearly drop in equilvalent to @auth0/auth0-react
Configure the SDK by wrapping your application in Auth0Provider:
// src/index.jsimportReactfrom"react";importReactDOMfrom"react-dom";import{Auth0Provider}from"@developertown/oidc-provider";importAppfrom"./App";ReactDOM.render(<Auth0Providerdomain="YOUR_AUTH0_DOMAIN"audience="YOUR_API_DOMAIN"clientId="YOUR_AUTH0_CLIENT_ID"redirectUri={window.location.origin}><App/></Auth0Provider>,document.getElementById("app"));Use the useAuth0 hook in your components to access authentication state (isLoading, isAuthenticated and user) and authentication methods (loginWithRedirect and logout):
// src/App.jsimportReactfrom"react";import{useAuth0}from"@developertown/oidc-provider";functionApp(){const{
isLoading,
isAuthenticated,
error,
user,
loginWithRedirect,
logout,}=useAuth0();if(isLoading){return<div>Loading...</div>;}if(error){return<div>Oops... {error.message}</div>;}if(isAuthenticated){return(<div>
Hello {user.name}{" "}<buttononClick={()=>{// optionally pass a returnTo url// https://auth0.com/docs/authenticate/login/logout/redirect-users-after-logoutlogout({extraQueryParams: {returnTo: `${window.location.origin}/logout/callback`,},});// or simply logut to return to the configured redirectUri//logout()}}>
Log out
</button></div>);}else{return(<buttononClick={()=>{//optionally pass a returnTo urlloginWithRedirect({state: {returnTo: `${window.location.href}/login/callback`},});// or take the defaults//loginWithRedirect()}}>
Log in
</button>);}}exportdefaultApp;Configure the SDK by wrapping your application in CognitoProvider:
// src/index.jsimportReactfrom"react";importReactDOMfrom"react-dom";import{CognitoProvider}from"@developertown/oidc-provider";importAppfrom"./App";ReactDOM.render(<CognitoProviderdomain="YOUR_COGNITO_DOMAIN"issuer="YOUR_COGNITO_ISSUER"clientId="YOUR_COGNITO_CLIENT_ID"redirectUri={window.location.origin}><App/></CognitoProvider>,document.getElementById("app"));Use the useCongito hook in your components to access authentication state (isLoading, isAuthenticated and user) and authentication methods (loginWithRedirect and logout):
// src/App.jsimportReactfrom"react";import{useCongito}from"@developertown/oidc-provider";functionApp(){const{
isLoading,
isAuthenticated,
error,
user,
loginWithRedirect,
logout,}=useCongito();if(isLoading){return<div>Loading...</div>;}if(error){return<div>Oops... {error.message}</div>;}if(isAuthenticated){return(<div>
Hello {user.name}<buttononClick={()=>logout()}>Log out</button></div>);}else{return<buttononClick={loginWithRedirect}>Log in</button>;}}exportdefaultApp;Configure the SDK by wrapping your application in AzureProvider:
// src/index.jsimportReactfrom"react";importReactDOMfrom"react-dom";import{AzureProvider}from"@developertown/oidc-provider";importAppfrom"./App";ReactDOM.render(<AzureProviderdomain="AZURE_AD_TENANT.b2clogin.com/AZURE_AD_TENANT.onmicrosoft.com"policy="b2c_1a_signup_signin"issuer="YOUR_AZURE_AD__ISSUER"clientId="YOUR_AZURE_AD_CLIENT_ID"clientSecret="YOUR_AZURE_AD_CLIENT_SECRET"redirectUri={window.location.origin}><App/></AzureProvider>,document.getElementById("app"));Use the useAzure hook in your components to access authentication state (isLoading, isAuthenticated and user) and authentication methods (loginWithRedirect and logout):
// src/App.jsimportReactfrom"react";import{useAzure}from"@developertown/oidc-provider";functionApp(){const{
isLoading,
isAuthenticated,
error,
user,
loginWithRedirect,
logout,}=useAzure();if(isLoading){return<div>Loading...</div>;}if(error){return<div>Oops... {error.message}</div>;}if(isAuthenticated){return(<div>
Hello {user.name}<buttononClick={()=>logout()}>Log out</button></div>);}else{return<buttononClick={loginWithRedirect}>Log in</button>;}}exportdefaultApp;This library can be configured to work with an OpenID Connect authentication provider. Configure the SDK by wrapping your application in OIDCProvider see IdentityModel/oidc-client-js for the full list of options when configuring the OIDCProvider:
// src/index.jsimportReactfrom"react";importReactDOMfrom"react-dom";import{OIDCProvider}from"@developertown/oidc-provider";importAppfrom"./App";ReactDOM.render(<OIDCProviderauthority={"YOUR_OIDC_DOMAIN"}metadata={{issuer: "YOUR_OIDC_ISSUER",authorization_endpoint: "YOUR_OIDC_AUTHORIZATION_ENDPOINT",token_endpoint: "YOUR_OIDC_TOKEN_ENDPOINT",end_session_endpoint: "YOUR_OIDC_END_SESSION_ENDPOINT",}}client_id={"YOUR_OIDC_CLIENT_ID"}response_type="code"loadUserInfo={false}automaticSilentRenewredirect_uri={window.location.origin}post_logout_redirect_uri={window.location.origin}><App/></OIDCProvider>,document.getElementById("app"));Use the useAuth hook in your components to access authentication state (isLoading, isAuthenticated and user) and authentication methods (loginWithRedirect and logout):
// src/App.jsimportReactfrom"react";import{useAuth}from"@developertown/oidc-provider";functionApp(){const{
isLoading,
isAuthenticated,
error,
user,
loginWithRedirect,
logout,}=useAuth();if(isLoading){return<div>Loading...</div>;}if(error){return<div>Oops... {error.message}</div>;}if(isAuthenticated){return(<div>
Hello {user.name}<buttononClick={()=>logout()}>Log out</button></div>);}else{return<buttononClick={loginWithRedirect}>Log in</button>;}}exportdefaultApp;Protect a route component using the withAuthenticationRequired higher order component. Visits to this route when unauthenticated will redirect the user to the login page and back to this page after login:
importReactfrom"react";import{withAuthenticationRequired}from"@developertown/oidc-provider";constPrivateRoute=()=><div>Private</div>;exportdefaultwithAuthenticationRequired(PrivateRoute,{// optionally show a message while the authentication provider initializes.onInitializing: ()=><div>Checking for existing login...</div>,// optionally show a message while the user waits to be redirected to the login page.onRedirecting: ()=><div>Redirecting you to the login page...</div>,// optionally show a message login fails.onError: (error: Error)=><div>{error.message}</div>,// optionally pass parameters to `loginWithRedirect` for example a returnTo locationloginWithRedirectParams: ()=>({state: {returnTo: window.location.href},}),});Call a protected API with an Access Token:
importReact,{useEffect,useState}from"react";import{useAuth}from"@developertown/oidc-provider";constPosts=()=>{const{ getAccessTokenSilently }=useAuth();const[posts,setPosts]=useState(null);useEffect(()=>{(async()=>{try{consttoken=awaitgetAccessTokenSilently();constresponse=awaitfetch("https://api.example.com/posts",{headers: {Authorization: `Bearer ${token}`,},});setPosts(awaitresponse.json());}catch(e){console.error(e);}})();},[getAccessTokenSilently]);if(!posts){return<div>Loading...</div>;}return(<ul>{posts.map((post,index)=>{return<likey={index}>{post}</li>;})}</ul>);};exportdefaultPosts;// src/index.jsimportReactfrom"react";importReactDOMfrom"react-dom";import{Auth0ProviderasAuthenticationProvider,AppState,}from"@developertown/oidc-provider";importAppfrom"./App";ReactDOM.render(<AuthenticationProviderdomain="YOUR_DOMAIN"clientId="YOUR_CLIENT_ID"redirectUri={window.location.origin}useRefreshTokensonAccessTokenChanged={(accessToken: string)=>{/* Do something with the accessToken*/// dispatch(accessTokenChanged(accessToken))// NOTE: this event may not be needed since getAccessTokenSilently() will always grab the latest access token// or perform a silent refresh to get a fresh one}}onAccessTokenExpiring={()=>{// Let the user know their session is expiring// NOTE: when useRefreshTokens is true accessTokens will be automatically refreshed}}onAccessTokenExpired={()=>{// Let the user know their session has expired// NOTE: when useRefreshTokens is true as long as the silent refresh occurs successfully the token will not expire}}onAccessTokenRefreshError={(error: Error)=>{// Handle errors when silently refreshing access tokens. Only applies when useRefreshTokens is true}}onRedirectCallback={(appState?: AppState)=>{// Perform action after redirecting from the authentication provider// NOTE: if no onRedirectCallback is provided the default behavior iswindow.history.replaceState({},document.title,appState?.returnTo||window.location.pathname);}}><App/></AuthenticationProvider>,document.getElementById("app"));This project is licensed under the MIT license. See the LICENSE file for more info.