Skip to main content

Authentication and Authorization in React

In this tutorial, we will learn about implementing authentication and authorization in a React application. We'll cover the basics of setting up user login, handling authentication state, and protecting routes.

Setting Up a Login Form

First, let's create a simple login form with username and password inputs. You can also use an existing authentication service, like Firebase, Auth0, or your custom server-side authentication.

JavaScript
import React, { useState } from 'react';

function LoginForm({ handleLogin }) {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');

const handleSubmit = event => {
event.preventDefault();
handleLogin({ username, password });
};

return (
<form onSubmit={handleSubmit}>
<label htmlFor="username">Username:</label>
<input id="username" type="text" value={username} onChange={e => setUsername(e.target.value)} />
<br />
<label htmlFor="password">Password:</label>
<input id="password" type="password" value={password} onChange={e => setPassword(e.target.value)} />
<br />
<button type="submit">Log in</button>
</form>
);
}

export default LoginForm;

Handling Authentication State

To manage authentication state, we will create an AuthContext using React's Context API. We'll store the user's authentication status and expose functions for logging in and out.

JavaScript
import { createContext, useState } from 'react';

const AuthContext = createContext();

function AuthProvider({ children }) {
const [isAuthenticated, setIsAuthenticated] = useState(false);

const login = credentials => {
// Here you should call your authentication API or service
// If the credentials are valid, update the authentication state
setIsAuthenticated(true);
};

const logout = () => {
setIsAuthenticated(false);
};

return <AuthContext.Provider value={{ isAuthenticated, login, logout }}>{children}</AuthContext.Provider>;
}

export { AuthContext, AuthProvider };

Now, wrap your application with the AuthProvider in the root component:

JavaScript
import { AuthProvider } from './auth/AuthContext';
import App from './App';

function Root() {
return (
<AuthProvider>
<App />
</AuthProvider>
);
}

export default Root;

Protecting Routes

To protect routes, we will create a PrivateRoute component that checks the user's authentication status before rendering the desired component. If the user is not authenticated, they will be redirected to the login page.

JavaScript
import React, { useContext } from 'react';
import { Route, Redirect } from 'react-router-dom';
import { AuthContext } from './auth/AuthContext';

function PrivateRoute({ component: Component, ...rest }) {
const { isAuthenticated } = useContext(AuthContext);

return <Route {...rest} render={props => (isAuthenticated ? <Component {...props} /> : <Redirect to="/login" />)} />;
}

export default PrivateRoute;

Now you can use the PrivateRoute component to protect any routes in your application:

JavaScript
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import PrivateRoute from './PrivateRoute';
import Dashboard from './Dashboard';
import LoginForm from './LoginForm';

function App() {
return (
<Router>
<Switch>
<Route path="/login" component={LoginForm} />
<PrivateRoute path="/dashboard" component={Dashboard} />
</Switch>
</Router>
);
}

export default App;

Implementing the Login Process

Now, let's use the login function from our AuthContext in the LoginForm component:

JavaScript
import React, { useContext } from 'react';
import { AuthContext } from './auth/AuthContext';

function LoginForm() {
// ... useState and handleSubmit

const { login } = useContext(AuthContext);

const handleSubmit = event => {
event.preventDefault();
login({ username, password });
};

// ... return form
}

export default LoginForm;

After successfully logging in, you can redirect the user to the protected route using React Router's useHistory hook:

JavaScript
import React, { useContext } from 'react';
import { useHistory } from 'react-router-dom';
import { AuthContext } from './auth/AuthContext';

function LoginForm() {
// ... useState

const history = useHistory();
const { login } = useContext(AuthContext);

const handleSubmit = event => {
event.preventDefault();
login({ username, password });
history.push('/dashboard');
};

// ... return form
}

export default LoginForm;

Conclusion

That's it! You now have a basic understanding of how to implement authentication and authorization in a React application. Remember to customize the authentication process according to your specific API or authentication service.