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.