A autenticação com JWT (JSON Web Token) é uma das abordagens mais utilizadas atualmente para proteger rotas e recursos em aplicações web modernas. Neste artigo, você vai aprender como implementar JWT em um backend com Node.js e integrá-lo a um frontend em React.
O que é JWT?
JWT (JSON Web Token) é um padrão aberto (RFC 7519) que define uma forma compacta e segura de transmitir informações entre partes como um objeto JSON. Ele é amplamente utilizado para autenticação porque é fácil de usar, leve e sem estado.
Estrutura do Projeto
Dividiremos a implementação em duas partes:
- Backend (Node.js com Express)
- Frontend (React)
1. Criando o Backend com Node.js
Instale as dependências:
npm init -y npm install express jsonwebtoken bcryptjs cors dotenv
Estrutura do projeto:
/backend |- server.js |- .env |- /routes |- auth.js |- /middleware |- authMiddleware.js |- /controllers |- authController.js
Arquivo .env
****:
env CopyEdit JWT_SECRET=minhachavesecreta
server.js
const express = require("express"); const cors = require("cors"); require("dotenv").config(); const app = express(); app.use(cors()); app.use(express.json()); const authRoutes = require("./routes/auth"); app.use("/api/auth", authRoutes); app.listen(5000, () => console.log("Servidor rodando na porta 5000"));
routes/auth.js
const express = require("express"); const router = express.Router(); const { login, protectedRoute } = require("../controllers/authController"); const authMiddleware = require("../middleware/authMiddleware"); router.post("/login", login); router.get("/protected", authMiddleware, protectedRoute); module.exports = router;
controllers/authController.js
const jwt = require("jsonwebtoken"); const bcrypt = require("bcryptjs"); const users = [ { id: 1, username: "admin", password: bcrypt.hashSync("123456", 8) }, ]; exports.login = (req, res) => { const { username, password } = req.body; const user = users.find((u) => u.username === username); if (!user || !bcrypt.compareSync(password, user.password)) { return res.status(401).json({ message: "Credenciais inválidas" }); } const token = jwt.sign({ id: user.id }, process.env.JWT_SECRET, { expiresIn: "1h", }); res.json({ token }); }; exports.protectedRoute = (req, res) => { res.json({ message: "Rota protegida acessada com sucesso!", userId: req.userId, }); };
middleware/authMiddleware.js
const jwt = require("jsonwebtoken"); module.exports = (req, res, next) => { const token = req.headers["authorization"]; if (!token) return res.status(403).json({ message: "Token não fornecido" }); jwt.verify(token, process.env.JWT_SECRET, (err, decoded) => { if (err) return res.status(401).json({ message: "Token inválido" }); req.userId = decoded.id; next(); }); };
2. Criando o Frontend com React
Instale as dependências:
npx create-react-app frontend cd frontend npm install axios react-router-dom
Estrutura simplificada:
/frontend |- App.js |- Login.js |- Protected.js
Login.js
import React, { useState } from "react"; import axios from "axios"; const Login = ({ setToken }) => { const [form, setForm] = useState({ username: "", password: "" }); const handleChange = (e) => setForm({ ...form, [e.target.name]: e.target.value }); const handleSubmit = async (e) => { e.preventDefault(); try { const response = await axios.post( "http://localhost:5000/api/auth/login", form ); setToken(response.data.token); } catch (error) { alert("Login falhou"); } }; return ( <form onSubmit={handleSubmit}> <input name="username" placeholder="Usuário" onChange={handleChange} /> <input name="password" type="password" placeholder="Senha" onChange={handleChange} /> <button type="submit">Entrar</button> </form> ); }; export default Login;
Protected.js
import React, { useEffect, useState } from "react"; import axios from "axios"; const Protected = ({ token }) => { const [message, setMessage] = useState(""); useEffect(() => { axios .get("http://localhost:5000/api/auth/protected", { headers: { Authorization: token }, }) .then((res) => setMessage(res.data.message)) .catch(() => setMessage("Acesso negado")); }, [token]); return <h1>{message}</h1>; }; export default Protected;
App.js
import React, { useState } from "react"; import Login from "./Login"; import Protected from "./Protected"; function App() { const [token, setToken] = useState(""); return ( <div> {!token ? <Login setToken={setToken} /> : <Protected token={token} />} </div> ); } export default App;
Considerações Finais
A autenticação com JWT é poderosa, mas deve ser usada com cuidado:
- Sempre armazene o token com segurança (ex:
localStorage
,sessionStorage
ou em cookies httpOnly). - Expire os tokens após um tempo razoável.
- Considere usar refresh tokens para manter sessões ativas.