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.
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.
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:
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.
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:
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:
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:
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.