Home > Article > Web Front-end > Authentication with JWT on Frontend and Backend: Implementing with Node.js and ReactJS (in TypeScript)
Authentication via JSON Web Token (JWT) is widely used to secure APIs and ensure that only authorized users can access certain data. In this post, we will show you how to configure JWT on the backend with Node.js and on the frontend with ReactJS using TypeScript, from token generation to secure user session management.
First, let's create an API with Node.js, Express and TypeScript that generates and validates JWT tokens.
Create a new project and install the main dependencies:
npm init -y npm install express jsonwebtoken bcryptjs dotenv npm install -D typescript @types/node @types/express @types/jsonwebtoken @types/bcryptjs ts-node
Create a tsconfig.json file for TypeScript configuration:
{ "compilerOptions": { "target": "es6", "module": "commonjs", "outDir": "./dist", "strict": true, "esModuleInterop": true }, "include": ["src/**/*.ts"], "exclude": ["node_modules"] }
Create a simple structure, starting with a server.ts file and a routes folder to organize authentication routes.
import express, { Application } from 'express'; import dotenv from 'dotenv'; import authRoutes from './routes/authRoutes'; dotenv.config(); const app: Application = express(); app.use(express.json()); app.use('/api/auth', authRoutes); const PORT = process.env.PORT || 5000; app.listen(PORT, () => console.log(`Servidor rodando na porta ${PORT}`));
Create a file for authentication routes. Here we will have a login route that will validate the user and return the JWT token.
import express, { Request, Response } from 'express'; import jwt from 'jsonwebtoken'; import bcrypt from 'bcryptjs'; const router = express.Router(); // Simulação de banco de dados const users = [{ username: 'usuario', password: 'senha123' }]; router.post('/login', async (req: Request, res: Response) => { const { username, password } = req.body; const user = users.find(u => u.username === username); if (!user || !(await bcrypt.compare(password, user.password))) { return res.status(401).json({ message: 'Credenciais inválidas' }); } const token = jwt.sign({ username }, process.env.JWT_SECRET as string, { expiresIn: '1h' }); res.json({ token }); }); export default router;
Add middleware to protect routes that require authentication.
import { Request, Response, NextFunction } from 'express'; import jwt from 'jsonwebtoken'; interface JwtPayload { username: string; } export const authMiddleware = (req: Request, res: Response, next: NextFunction): void => { const token = req.headers['authorization']; if (!token) { res.status(403).json({ message: 'Token não fornecido' }); return; } jwt.verify(token, process.env.JWT_SECRET as string, (err, decoded) => { if (err) { res.status(401).json({ message: 'Token inválido' }); return; } req.user = decoded as JwtPayload; next(); }); };
On the frontend, we will use React to handle authentication, sending credentials, and storing the JWT token.
First, create a Login.tsx component to capture the user's credentials and send a login request to the backend.
import React, { useState } from 'react'; import axios from 'axios'; const Login: React.FC = () => { const [username, setUsername] = useState<string>(''); const [password, setPassword] = useState<string>(''); const [error, setError] = useState<string>(''); const handleLogin = async (e: React.FormEvent) => { e.preventDefault(); try { const response = await axios.post('/api/auth/login', { username, password }); localStorage.setItem('token', response.data.token); window.location.href = '/dashboard'; } catch (err) { setError('Credenciais inválidas'); } }; return ( <form onSubmit={handleLogin}> <input type="text" placeholder="Username" value={username} onChange={(e) => setUsername(e.target.value)} /> <input type="password" placeholder="Password" value={password} onChange={(e) => setPassword(e.target.value)} /> <button type="submit">Login</button> {error && <p>{error}</p>} </form> ); }; export default Login;
Create a function for protected routes, using the JWT token to access the API.
import React from 'react'; import { Route, Redirect, RouteProps } from 'react-router-dom'; interface PrivateRouteProps extends RouteProps { component: React.ComponentType<any>; } const PrivateRoute: React.FC<PrivateRouteProps> = ({ component: Component, ...rest }) => ( <Route {...rest} render={(props) => localStorage.getItem('token') ? ( <Component {...props} /> ) : ( <Redirect to="/login" /> ) } /> ); export default PrivateRoute;
Configure axios to automatically include the JWT token in protected requests.
import axios from 'axios'; const token = localStorage.getItem('token'); if (token) { axios.defaults.headers.common['Authorization'] = token; } export default axios;
Now, create an example of a protected page that requires the token to access.
import React, { useEffect, useState } from 'react'; import axios from './axiosConfig'; const Dashboard: React.FC = () => { const [data, setData] = useState<string>(''); useEffect(() => { const fetchData = async () => { try { const response = await axios.get('/api/protected'); setData(response.data.message); } catch (error) { console.error(error); } }; fetchData(); }, []); return <h1>{data || 'Carregando...'}</h1>; }; export default Dashboard;
With these steps, we set up full JWT authentication in TypeScript for a project that uses Node.js on the backend and React on the frontend. This approach is highly secure, efficient and widely adopted to protect modern applications.
The above is the detailed content of Authentication with JWT on Frontend and Backend: Implementing with Node.js and ReactJS (in TypeScript). For more information, please follow other related articles on the PHP Chinese website!