React¶
React is one of the most popular JavaScript framework to build dynamic applications for the browser.
The Fief JavaScript client provides tools to help you integrate Fief authentication in your React project. Let's see how to use them!
Install the client¶
Application example¶
This is for you if...
- You want to handle all the OAuth authentication in your React application.
Prerequisites
- You have a React project setup.
- Make sure your Fief Client is Public.
- Allow the following Redirect URI on your Fief Client:
http://localhost:3000/callback
In this example, we'll show you how to use the components and hooks provided by Fief to authenticate users and protect routes using React Router.
Setup FiefAuthProvider
¶
The FiefAuthProvider
is a component providing all the necessary context for Fief, especially the Fief client and user session state. Every component nested inside this component will have access to the Fief hooks.
import { FiefAuthProvider } from '@fief/fief/react';
import { Routes, Route } from 'react-router-dom';
import Callback from './Callback';
import Public from './Public';
import Private from './Private';
import Header from './Header';
import RequireAuth from './RequireAuth';
function App() {
return (
<FiefAuthProvider // (1)!
baseURL="https://fief.mydomain.com"
clientId="NFL8Ycdag-gbvO-5pJezwCmFEouCDRhCG4paUNOaDoI"
>
<div className="App">
<h1>Fief React example</h1>
<Header /> {/* (2)! */}
<Routes> {/* (3)! */}
<Route path="/" element={<Public />} /> {/* (4)! */}
<Route path="/private" element={<RequireAuth><Private /></RequireAuth>} /> {/* (5)! */}
<Route path="/callback" element={<Callback />} /> {/* (6)! */}
</Routes>
</div>
</FiefAuthProvider>
);
}
export default App;
-
Declare the
FiefAuthProvider
This is necessary to give to nested components the right Fief context and makes the hooks working.
It takes as properties the same arguments as the
Fief
client. -
A
Header
componentContains the navigation. We'll detail it in a moment.
-
The
Routes
component from React Router -
A public route
This route will be accessible by any visitor, even if not logged in.
-
A private route
This route will be accessible only by logged in users. To do this, we wrap it in a
RequireAuth
component. We'll detail it in a moment. -
A callback route
The route where Fief will redirect the user to after a successful login to complete the OAuth authentication.
At this point, your React app has everything it needs to use Fief authentication tools!
Implement callback route¶
After the user has successfully logged in on Fief, they will be redirected to your callback route. It needs to exchange the authorization code with a proper access token.
The role of this route is then just to perform this task before redirecting to another route.
import { useFiefAuth } from '@fief/fief/react';
import { useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
const Callback: React.FunctionComponent = () => {
const fiefAuth = useFiefAuth(); // (1)!
const navigate = useNavigate();
useEffect(() => {
fiefAuth.authCallback(`${window.location.protocol}//${window.location.host}/callback`).then(() => { // (2)!
navigate('/');
});
}, [fiefAuth, navigate]);
return (
<p>Callback!</p>
);
};
export default Callback;
-
Hook to get the
FiefAuth
classThis is the browser helper provided by the Fief JavaScript client.
-
We call the
authCallback
methodThis method takes care of everything: retrieving the authorization code in the query parameters, exchanging it with a fresh access token and save it in the browser session.
Once the promise is resolved, all we have to do is to redirect back to the index page.
Protect private routes¶
Usually, you'll need to prevent visitors from accessing a page if they're not logged in.
To do this, we implement a simple component that'll check for the authentication state and automatically redirect to the Fief authentication page if the user is not logged in.
import { useFiefAuth, useFiefIsAuthenticated } from '@fief/fief/react';
import React, { useEffect } from 'react';
const RequireAuth: React.FunctionComponent<React.PropsWithChildren> = ({ children }) => {
const fiefAuth = useFiefAuth(); // (1)!
const isAuthenticated = useFiefIsAuthenticated(); // (2)!
useEffect(() => {
if (!isAuthenticated) {
fiefAuth.redirectToLogin(`${window.location.protocol}//${window.location.host}/callback`); // (3)!
}
}, [fiefAuth, isAuthenticated]);
return (
<>
{isAuthenticated && children}
</>
);
};
export default RequireAuth;
-
Hook to get the
FiefAuth
classThis is the browser helper provided by the Fief JavaScript client.
-
Hook to get the authentication state
This hook simply returns a boolean stating if a user is logged in or not.
-
Redirect to Fief authentication page
With this effect, we automatically redirect the user to the Fief authentication page so that they can log in.
The
redirectToLogin
method only needs the redirect URL where the user will be redirected after a successful authentication on Fief: the/callback
route.
Manage authentication¶
You have access to a set of hooks to help you manage the authentication state of the user, like retrieving their information, redirect them to the authentication page or logout them.
In the example below, we show a simple header with navigation links and a login or logout button.
import { useFiefAuth, useFiefIsAuthenticated, useFiefUserinfo } from '@fief/fief/react';
import React, { useCallback } from 'react';
import { Link } from 'react-router-dom';
const Header: React.FunctionComponent = () => {
const fiefAuth = useFiefAuth();
const isAuthenticated = useFiefIsAuthenticated();
const userinfo = useFiefUserinfo(); // (1)!
const login = useCallback(() => { // (2)!
fiefAuth.redirectToLogin(`${window.location.protocol}//${window.location.host}/callback`);
}, [fiefAuth]);
const logout = useCallback(() => { // (3)!
fiefAuth.logout(`${window.location.protocol}//${window.location.host}`);
}, [fiefAuth]);
return (
<ul>
<li><Link to="/">Public page</Link></li>
<li><Link to="/private">Private page</Link></li>
<li>
{!isAuthenticated && <button type="button" onClick={() => login()}>Login</button>}
{isAuthenticated && userinfo && (
<div>
<span>{userinfo.email}</span>
<button type="button" onClick={() => logout()}>Logout</button>
</div>
)}
</li>
</ul>
);
};
export default Header;
-
Hook to get user information
It'll return you an object with the user information, or
null
if no user is authenticated. -
Callback to redirect to Fief authentication page
When the login button is clicked, this callback will redirect to the Fief authentication page. This is exactly the same thing we showed in the
RequireAuth
component. -
Callback to logout
When the logout button is clicked, this callback will start the logout process.
The
FiefAuth
helper takes care of clearing the local session and redirect to the Fief logout page so that the session on Fief's side can also be cleared.All it needs is the redirect URL where the user will be redirected after a successful logout. Here, we go back to the index route.
Call an API with an access token¶
In most cases, you'll have an API backend from which you can read or write data to display to the user in your web application.
To secure your API, you can make it require a valid Fief access token, so we are sure the call is made from an authenticated user. This is what we show for example in the FastAPI or Flask API examples.
From your browser application, you can perform XHR requests in JavaScript. All you need is to pass a valid access token in the Authorization
header of your request.
When a user is authenticated, you can get the current access token using the useFiefTokenInfo
hook. We show below an example of an HTTP request made to your backend using fetch
: