DEV Community

Cover image for Autenticação com JWT no Frontend e Backend: Implementando com Node.js e ReactJS (em TypeScript)
Lucas Pereira de Souza
Lucas Pereira de Souza

Posted on

2

Autenticação com JWT no Frontend e Backend: Implementando com Node.js e ReactJS (em TypeScript)

A autenticação via JSON Web Token (JWT) é amplamente utilizada para proteger APIs e garantir que apenas usuários autorizados possam acessar determinados dados. Neste post, vamos mostrar como configurar o JWT no backend com Node.js e no frontend com ReactJS usando TypeScript, desde a geração do token até o gerenciamento seguro de sessões de usuário.

Configurando o Backend com Node.js

Primeiro, vamos criar uma API com Node.js, Express e TypeScript que gere e valide tokens JWT.

Passo 1: Configurando o Ambiente

Crie um novo projeto e instale as dependências principais:

npm init -y
npm install express jsonwebtoken bcryptjs dotenv
npm install -D typescript @types/node @types/express @types/jsonwebtoken @types/bcryptjs ts-node
Enter fullscreen mode Exit fullscreen mode

Crie um arquivo tsconfig.json para a configuração do TypeScript:

{
  "compilerOptions": {
    "target": "es6",
    "module": "commonjs",
    "outDir": "./dist",
    "strict": true,
    "esModuleInterop": true
  },
  "include": ["src/**/*.ts"],
  "exclude": ["node_modules"]
}
Enter fullscreen mode Exit fullscreen mode

Passo 2: Estruturando o Backend

Crie uma estrutura simples, começando com um arquivo server.ts e uma pasta routes para organizar as rotas de autenticação.

server.ts

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}`));
Enter fullscreen mode Exit fullscreen mode

routes/authRoutes.ts

Crie um arquivo para as rotas de autenticação. Aqui, teremos uma rota de login que validará o usuário e retornará o token JWT.

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;
Enter fullscreen mode Exit fullscreen mode

Passo 3: Protegendo Rotas com Middleware

Adicione um middleware para proteger rotas que exigem autenticação.

middleware/authMiddleware.ts

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();
    });
};
Enter fullscreen mode Exit fullscreen mode

Configurando o Frontend com ReactJS

No frontend, usaremos React para lidar com a autenticação, envio de credenciais e armazenamento do token JWT.

Passo 1: Configurando a Interface de Login

Primeiro, crie um componente Login.tsx para capturar as credenciais do usuário e enviar uma solicitação de login para o backend.

Login.tsx

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;
Enter fullscreen mode Exit fullscreen mode

Passo 2: Proteger Rotas no Frontend

Crie uma função para rotas protegidas, utilizando o token JWT para acessar a API.

PrivateRoute.tsx

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;
Enter fullscreen mode Exit fullscreen mode

Passo 3: Enviar o Token JWT nas Requisições

Configure o axios para incluir automaticamente o token JWT nas requisições protegidas.

axiosConfig.ts

import axios from 'axios';

const token = localStorage.getItem('token');
if (token) {
    axios.defaults.headers.common['Authorization'] = token;
}

export default axios;
Enter fullscreen mode Exit fullscreen mode

Passo 4: Exemplo de Uso com uma Rota Protegida

Agora, crie um exemplo de página protegida que exija o token para acessar.

Dashboard.tsx

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;
Enter fullscreen mode Exit fullscreen mode

Conclusão

Com essas etapas, configuramos uma autenticação JWT completa em TypeScript para um projeto que utiliza Node.js no backend e React no frontend. Essa abordagem é altamente segura, eficiente e amplamente adotada para proteger aplicações modernas.

Heroku

This site is built on Heroku

Join the ranks of developers at Salesforce, Airbase, DEV, and more who deploy their mission critical applications on Heroku. Sign up today and launch your first app!

Get Started

Top comments (1)

Collapse
 
engrsakib profile image
Md Nazmus Sakib

nice

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay