React authentication patterns: context, hooks, and protected routes

Introduction to React Authentication Patterns

As applications grow in complexity, so does the need for robust authentication systems. In a React application, authentication patterns often involve context, hooks, and protected routes. These patterns help keep authentication logic out of business logic, ensuring a clean and maintainable codebase.

AuthContext: Centralizing Authentication State

One of the most effective ways to manage authentication state in a React application is by using the AuthContext. This context allows you to wrap your application with authentication state, making it accessible to any component in your app.

const AuthContext = React.createContext();
      

By creating a context, you can provide authentication state to your components, making it easier to manage and reuse across your application.

Tip: Always use the useContext hook to access the context in your components.

useAuth Hook: Simplifying Authentication Logic

Another powerful pattern in React authentication is the useAuth hook. This hook encapsulates authentication logic, such as token refresh, and makes it reusable across your application.

const useAuth = () => {
        const [auth, setAuth] = React.useState(null);
        const [token, setToken] = React.useState(null);
      
        const refresh = () => {
          // logic to refresh token
        };
      
        return { auth, setAuth, token, setToken, refresh };
      };
      

This hook can be used in any component to access authentication state and perform actions like token refresh.

PrivateRoute: Protecting Routes from Unauthorized Access

When it comes to protecting routes in a React application, the PrivateRoute component is a powerful tool. This component allows you to define routes that are only accessible to authenticated users.

const PrivateRoute = ({ children, ...rest }) => {
        const auth = useAuth();
        return (
          
              auth.auth ? (
                children
              ) : (
                
              )
            }
          />
        );
      };
      

This component can be used in your routing configuration to ensure that only authenticated users can access certain routes.

Warning: Always ensure that your authentication logic is secure and that sensitive data is not exposed.

Token Refresh on 401: Handling Authentication Errors

One of the most common issues in authentication is handling 401 errors, which indicate that the token has expired. In a React application, you can handle this by implementing a token refresh mechanism.

const refresh = () => {
        // logic to refresh token
      };
      

This function can be called when a 401 error is encountered, ensuring that the user remains authenticated without having to log in again.

Conclusion: Keeping Authentication Out of Business Logic

By using patterns like AuthContext, useAuth hook, PrivateRoute, and implementing token refresh on 401, you can keep authentication logic out of your business logic. This ensures a clean, maintainable, and secure codebase.

At Bastionary, we provide a self-hosted platform for authentication, billing, licensing, and feature flags. By integrating with Bastionary, you can ensure that your authentication system is