Logo Passei Direto
Buscar
Material
páginas com resultados encontrados.
páginas com resultados encontrados.

Prévia do material em texto

Todos os materiais didáticos apresentados nesta plataforma são protegidos por direitos autorais de propriedade da Universidade Veiga 
de Almeida e do Centro Universitário Jorge Amado. Qualquer uso não autorizado, reprodução ou distribuição (incluindo o upload para 
sites) são estritamente proibidos e sujeitos às penalidades legais aplicáveis. Todos os direitos são reservados à UVA & Unijorge. 
Integração com Banco de Dados NoSQL 
e Autenticação 
 
Esta unidade aborda temas fundamentais para o desenvolvimento de aplicações web 
modernas e seguras, com foco na integração de sistemas backend a bancos de dados 
NoSQL, especialmente o MongoDB, além da implementação de autenticação e boas 
práticas de segurança. 
 
Em um cenário cada vez mais orientado a dados e acesso remoto, saber como 
armazenar, consultar e proteger informações é essencial para garantir o 
funcionamento confiável e ético das aplicações. 
 
A escolha por bancos NoSQL permite maior flexibilidade e escalabilidade, 
características importantes em projetos com dados não estruturados ou com rápida 
evolução. 
 
Já a autenticação e o controle de acesso asseguram que os dados sensíveis sejam 
acessados apenas por usuários autorizados. Assim, veremos como conectar APIs 
reais a bancos de dados, validar informações recebidas, aplicar filtros, proteger rotas e 
estruturar aplicações robustas, que refletem os padrões exigidos no mercado de 
trabalho atual. 
 
 
Objetivo 
 
Ao final desta unidade, você deverá ser capaz de: 
 
• Implementar soluções de backend integradas a bancos de dados NoSQL, 
incluindo autenticação e login de usuários, visando a segurança e a integridade 
dos dados. 
 
 
Conteúdo Programático 
 
Esta unidade está organizada de acordo com os seguintes temas: 
 
• Tema 1 - Integração com bancos de dados NoSQL (MongoDB) 
• Tema 2 - Implementando autenticação e login de usuários 
• Tema 3 - Boas práticas de segurança e validação de dados 
 
 
 
 
 
Todos os materiais didáticos apresentados nesta plataforma são protegidos por direitos autorais de propriedade da Universidade Veiga 
de Almeida e do Centro Universitário Jorge Amado. Qualquer uso não autorizado, reprodução ou distribuição (incluindo o upload para 
sites) são estritamente proibidos e sujeitos às penalidades legais aplicáveis. Todos os direitos são reservados à UVA & Unijorge. 
Já imaginou desenvolver um sistema que armazena dados de usuários, realiza login 
com segurança e protege informações sensíveis, como em uma loja virtual, um app de 
agendamento ou até mesmo uma rede social? 
 
Nesta unidade veremos como tornar isso realidade, integrando sua API com o banco 
de dados NoSQL MongoDB e implementando autenticação segura. 
 
Ao dominar esses conhecimentos, poderemos construir aplicações completas, que 
lidam com dados reais e exigem responsabilidade na gestão de acesso e segurança. 
Isso não só abre portas para oportunidades no mercado de trabalho, como também 
permite a criação de soluções pessoais — desde o gerenciamento de tarefas até o 
controle de finanças — com total autonomia. 
 
A cada passo dado, nos aproximamos mais do perfil de desenvolvedor fullstack que o 
mercado procura, ou seja, capaz de conectar dados, proteger usuários e entregar 
aplicações robustas e confiáveis. 
 
 
 
 
Todos os materiais didáticos apresentados nesta plataforma são protegidos por direitos autorais de propriedade da Universidade Veiga 
de Almeida e do Centro Universitário Jorge Amado. Qualquer uso não autorizado, reprodução ou distribuição (incluindo o upload para 
sites) são estritamente proibidos e sujeitos às penalidades legais aplicáveis. Todos os direitos são reservados à UVA & Unijorge. 
Tema 1 
Integração com bancos de dados NoSQL 
(MongoDB) 
 
 
Como armazenar e recuperar dados de forma flexível e 
escalável? 
 
Em aplicações web modernas, é fundamental contar com um banco de dados flexível, 
escalável e capaz de lidar com estruturas de dados dinâmicas. Nesse contexto, os 
bancos de dados NoSQL — e especialmente o MongoDB — vêm se destacando como 
uma solução ideal para aplicações que precisam evoluir rapidamente e trabalhar com 
diferentes formatos de informação. 
 
NoSQL significa Not Only SQL e descreve uma família de bancos que não 
utilizam o modelo relacional tradicional com tabelas e esquemas fixos. Ao 
contrário, eles adotam modelos mais flexíveis, como documentos, grafos 
ou colunas, permitindo que os dados sejam armazenados de forma mais 
natural para aplicações baseadas em objetos. 
 
O MongoDB, por exemplo, é um banco de dados orientado a documentos, no qual os 
dados são armazenados em objetos no formato BSON (uma versão binária do JSON). 
 
Isso significa que, em vez de uma tabela com colunas rígidas, cada “registro” é um 
documento com sua própria estrutura. Essa característica facilita muito o 
desenvolvimento de aplicações em JavaScript ou TypeScript, pois o mesmo formato 
de dados utilizado na aplicação (JSON) pode ser persistido diretamente no banco. 
 
Nota 
Além disso, o MongoDB permite escalar horizontalmente com facilidade, suportando 
grandes volumes de dados distribuídos entre diferentes servidores. 
 
Para integrar uma aplicação Node.js com MongoDB, geralmente utilizamos bibliotecas 
que facilitam a comunicação com o banco. A mais comum é o Mongoose, que permite 
definir “modelos” para os documentos e interagir com o banco de maneira mais 
estruturada. 
 
A seguir, veremos um exemplo de como fazer essa integração em uma aplicação 
utilizando Express e TypeScript. 
 
Observe as etapas apresentadas: 
 
 
 
Todos os materiais didáticos apresentados nesta plataforma são protegidos por direitos autorais de propriedade da Universidade Veiga 
de Almeida e do Centro Universitário Jorge Amado. Qualquer uso não autorizado, reprodução ou distribuição (incluindo o upload para 
sites) são estritamente proibidos e sujeitos às penalidades legais aplicáveis. Todos os direitos são reservados à UVA & Unijorge. 
1. Primeiramente, criamos um projeto com npm init e instalamos as dependências 
necessárias: 
 
 
npm install express mongoose 
npm install -D typescript @types/express ts-node-dev 
 
 
2. Em seguida, configuramos o tsconfig.json para usar TypeScript no projeto e 
criamos uma estrutura básica de servidor Express. 
 
Vamos considerar que queremos criar uma API de cadastro de tarefas (todo list). 
Começamos criando um arquivo chamado server.ts com o seguinte conteúdo: 
 
 
import express from 'express' 
import mongoose from 'mongoose' 
import dotenv from 'dotenv' 
 
dotenv.config() 
 
const app = express() 
app.use(express.json()) 
 
mongoose.connect(process.env.MONGO_URI || 'mongodb://localhost:27017/tarefas') 
 .then(() => console.log('Conectado ao MongoDB')) 
 .catch(err => console.error('Erro ao conectar:', err)) 
 
app.listen(3000, () => { 
 console.log('Servidor rodando na porta 3000') 
}) 
 
 
Esse código inicia o servidor Express, lê as variáveis de ambiente (como a string de 
conexão com o MongoDB) e tenta se conectar ao banco. 
 
Se a conexão for bem-sucedida, ele imprime uma mensagem no console. 
 
Agora que estamos conectados ao banco, podemos definir um modelo para 
armazenar nossas tarefas. 
 
1. Criamos um arquivo models/Tarefa.ts: 
 
 
import mongoose, { Schema, Document } from 'mongoose' 
 
export interface ITarefa extends Document { 
 titulo: string 
 concluida: boolean 
 dataCriacao: Date 
} 
 
const TarefaSchema: Schema = new Schema({ 
 
 
Todos os materiais didáticos apresentados nesta plataforma são protegidos por direitos autorais de propriedade da Universidade Veiga 
de Almeida e do Centro Universitário Jorge Amado. Qualquer uso não autorizado, reprodução ou distribuição (incluindo o upload para 
sites) são estritamente proibidos e sujeitos às penalidades legais aplicáveis. Todos os direitos são reservados à UVA & Unijorge. 
 titulo: { type: String, required: true}, 
 concluida: { type: Boolean, default: false }, 
 dataCriacao: { type: Date, default: Date.now } 
}) 
 
export default mongoose.model('Tarefa', TarefaSchema) 
 
 
Esse modelo define os campos esperados no documento: um título obrigatório, um 
campo booleano para marcar se a tarefa foi concluída e a data de criação. 
 
O uso de TypeScript permite garantir que o objeto terá o formato esperado ao longo da 
aplicação. 
 
2. Agora, vamos criar uma rota para salvar uma nova tarefa e outra para listar todas 
as tarefas salvas. 
 
No arquivo server.ts, adicionamos: 
 
 
import Tarefa from './models/Tarefa' 
 
app.post('/tarefas', async (req, res) => { 
 try { 
 const { titulo } = req.body 
 const novaTarefa = new Tarefa({ titulo }) 
 await novaTarefa.save() 
 res.status(201).json(novaTarefa) 
 } catch (err) { 
 res.status(400).json({ erro: 'Erro ao criar tarefa' }) 
 } 
}) 
 
app.get('/tarefas', async (req, res) => { 
 try { 
 const tarefas = await Tarefa.find() 
 res.status(200).json(tarefas) 
 } catch (err) { 
 res.status(500).json({ erro: 'Erro ao buscar tarefas' }) 
 } 
}) 
 
 
Essas rotas permitem a criação de tarefas por meio de uma requisição POST e a 
listagem de todas as tarefas cadastradas com uma requisição GET. 
 
Importante! 
Note que usamos async/await para lidar com operações assíncronas e garantimos o 
tratamento de erros com blocos try/catch, retornando códigos HTTP apropriados (201 
Created, 500 Internal Server Error etc.). 
 
Esse exemplo simples já demonstra como a integração com um banco NoSQL pode 
ser feita de forma direta e produtiva em uma aplicação real. 
 
 
Todos os materiais didáticos apresentados nesta plataforma são protegidos por direitos autorais de propriedade da Universidade Veiga 
de Almeida e do Centro Universitário Jorge Amado. Qualquer uso não autorizado, reprodução ou distribuição (incluindo o upload para 
sites) são estritamente proibidos e sujeitos às penalidades legais aplicáveis. Todos os direitos são reservados à UVA & Unijorge. 
 
A flexibilidade do MongoDB, somada à facilidade de manipulação de dados no 
formato JSON, torna o desenvolvimento mais ágil e adaptável a mudanças. 
 
Em vez de criar migrations ou alterar esquemas complexos como em bancos 
relacionais, podemos adicionar campos novos aos documentos de maneira natural e 
sem quebrar a estrutura anterior. 
 
Por outro lado, é importante lembrar que essa flexibilidade exige cuidado. A ausência 
de esquemas rígidos pode resultar em dados inconsistentes se não houver validações 
adequadas. Por isso, bibliotecas como Mongoose são úteis, pois oferecem uma 
camada de modelagem e validação que ajuda a manter a integridade dos dados. 
 
Além disso, trabalhar com um banco de dados requer pensar em segurança, 
autenticação e performance. 
 
Por isso, a integração de uma API com um banco de dados NoSQL como o MongoDB 
representa um passo importante na construção de sistemas reais e escaláveis. Ela 
permite que os dados da aplicação sejam persistidos de maneira eficaz e adaptável, e 
que possamos trabalhar com grandes volumes de informação sem comprometer a 
performance. 
 
Combinando esse conhecimento com autenticação, controle de acesso e boas 
práticas de segurança, o desenvolvedor estará preparado para enfrentar os desafios 
do desenvolvimento backend moderno com uma base sólida. 
 
 
 
 
 
Todos os materiais didáticos apresentados nesta plataforma são protegidos por direitos autorais de propriedade da Universidade Veiga 
de Almeida e do Centro Universitário Jorge Amado. Qualquer uso não autorizado, reprodução ou distribuição (incluindo o upload para 
sites) são estritamente proibidos e sujeitos às penalidades legais aplicáveis. Todos os direitos são reservados à UVA & Unijorge. 
Tema 2 
Implementando autenticação e login de usuários 
 
 
De que forma podemos garantir que apenas usuários 
autorizados acessem determinadas funcionalidades? 
 
Em qualquer aplicação web que lida com dados sensíveis ou funcionalidades 
personalizadas, o controle de acesso é essencial. 
 
Imagine um sistema por meio do qual qualquer pessoa pode editar informações de 
outro usuário ou acessar áreas privadas sem restrição. A ausência de autenticação 
colocaria em risco tanto a privacidade quanto a integridade dos dados. É por isso que 
a implementação de autenticação e login se tornou uma prática padrão no 
desenvolvimento web moderno. 
 
Neste tema veremos como permitir que usuários se cadastrem, façam login com 
segurança e acessem conteúdos restritos utilizando Node.js, Express e TypeScript, 
além de práticas seguras com criptografia de senhas e tokens JWT. 
 
Autenticação é o processo de confirmar 
que um usuário é quem ele diz ser. 
 
Em uma aplicação web, isso geralmente 
ocorre por meio de um formulário de 
login no qual o usuário informa suas 
credenciais (usuário/senha). 
 
 
O backend então verifica se os dados conferem com os armazenados no banco de 
dados. Se forem válidos, o usuário é autenticado e recebe acesso temporário à 
aplicação. 
 
Para isso, será criado um modelo de usuário com campos como nome, e-mail e 
senha, armazenados no MongoDB. 
 
No entanto, jamais devemos armazenar senhas em texto plano. Por isso, usamos a 
biblioteca bcrypt para realizar a hash (criptografia irreversível) das senhas. 
 
 
 
 
Todos os materiais didáticos apresentados nesta plataforma são protegidos por direitos autorais de propriedade da Universidade Veiga 
de Almeida e do Centro Universitário Jorge Amado. Qualquer uso não autorizado, reprodução ou distribuição (incluindo o upload para 
sites) são estritamente proibidos e sujeitos às penalidades legais aplicáveis. Todos os direitos são reservados à UVA & Unijorge. 
Instalamos as dependências da seguinte forma: 
 
 
npm install bcrypt jsonwebtoken 
npm install -D @types/bcrypt @types/jsonwebtoken 
 
 
A seguir, apresentamos um modelo User.ts usando Mongoose e TypeScript: 
 
 
import mongoose, { Document, Schema } from 'mongoose' 
 
export interface IUser extends Document { 
 nome: string 
 email: string 
 senha: string 
} 
 
const UserSchema: Schema = new Schema({ 
 nome: { type: String, required: true }, 
 email: { type: String, required: true, unique: true }, 
 senha: { type: String, required: true } 
}) 
 
export default mongoose.model('User', UserSchema) 
 
 
No momento do cadastro de um novo usuário, precisamos gerar a hash da senha 
antes de armazená-la. 
 
Isso é feito da seguinte forma: 
 
 
import express from 'express' 
import bcrypt from 'bcrypt' 
import User from './models/User' 
 
const router = express.Router() 
 
router.post('/registro', async (req, res) => { 
 const { nome, email, senha } = req.body 
 try { 
 const senhaHash = await bcrypt.hash(senha, 10) 
 const novoUsuario = new User({ nome, email, senha: senhaHash }) 
 await novoUsuario.save() 
 res.status(201).json({ mensagem: 'Usuário cadastrado com sucesso!' }) 
 } catch (err) { 
 res.status(500).json({ erro: 'Erro ao registrar usuário.' }) 
 } 
}) 
 
 
A função bcrypt.hash(senha, 10) aplica a criptografia e adiciona um salt (um valor 
aleatório) para aumentar a segurança. 
 
 
Todos os materiais didáticos apresentados nesta plataforma são protegidos por direitos autorais de propriedade da Universidade Veiga 
de Almeida e do Centro Universitário Jorge Amado. Qualquer uso não autorizado, reprodução ou distribuição (incluindo o upload para 
sites) são estritamente proibidos e sujeitos às penalidades legais aplicáveis. Todos os direitos são reservados à UVA & Unijorge. 
 
Agora, com o usuário registrado, podemos criar a rota de login, que verifica o e-mail, 
compara a senha informada com a senha armazenada e, se estiver tudo certo, gera 
um token JWT (JSON Web Token) para manter o usuário autenticado nas próximas 
requisições. 
 
 
import jwtfrom 'jsonwebtoken' 
 
router.post('/login', async (req, res) => { 
 const { email, senha } = req.body 
 try { 
 const usuario = await User.findOne({ email }) 
 if (!usuario) return res.status(401).json({ erro: 'Usuário não encontrado' 
}) 
 
 const senhaValida = await bcrypt.compare(senha, usuario.senha) 
 if (!senhaValida) return res.status(401).json({ erro: 'Senha inválida' }) 
 
 const token = jwt.sign( 
 { id: usuario._id, email: usuario.email }, 
 'chave-secreta', // essa chave deveria vir de uma variável de ambiente 
 { expiresIn: '1h' } 
 ) 
 
 res.status(200).json({ token }) 
 } catch (err) { 
 res.status(500).json({ erro: 'Erro ao realizar login.' }) 
 } 
}) 
 
 
Esse token é uma espécie de passe de acesso. 
 
Ele pode ser enviado pelo front-end a cada nova requisição em rotas protegidas, 
normalmente no seguinte cabeçalho: 
 
 
Authorization: Bearer 
 
 
No backend, será criado um middleware de autenticação que intercepta requisições 
e verifica se o token enviado é válido. Se não for, a requisição é negada. 
 
Isso garante que apenas usuários logados tenham acesso às funcionalidades 
privadas. 
 
 
import { Request, Response, NextFunction } from 'express' 
 
export function autenticarToken(req: Request, res: Response, next: 
NextFunction) { 
 const authHeader = req.headers['authorization'] 
 const token = authHeader && authHeader.split(' ')[1] 
 
 
Todos os materiais didáticos apresentados nesta plataforma são protegidos por direitos autorais de propriedade da Universidade Veiga 
de Almeida e do Centro Universitário Jorge Amado. Qualquer uso não autorizado, reprodução ou distribuição (incluindo o upload para 
sites) são estritamente proibidos e sujeitos às penalidades legais aplicáveis. Todos os direitos são reservados à UVA & Unijorge. 
 
 if (!token) return res.status(401).json({ erro: 'Acesso negado. Token 
ausente.' }) 
 
 jwt.verify(token, 'chave-secreta', (err, usuario) => { 
 if (err) return res.status(403).json({ erro: 'Token inválido ou expirado.' 
}) 
 req.body.usuario = usuario 
 next() 
 }) 
} 
 
 
Esse middleware pode ser aplicado a qualquer rota que deva ser protegida, como no 
exemplo a seguir: 
 
 
app.get('/perfil', autenticarToken, (req, res) => { 
 res.json({ mensagem: 'Bem-vindo ao seu perfil!' }) 
}) 
 
 
Assim, garantimos que apenas usuários autenticados possam acessar dados pessoais 
ou executar ações importantes na aplicação. 
 
Importante! 
Essa abordagem é amplamente utilizada em aplicações reais — como sistemas 
bancários, redes sociais, lojas on-line — e é essencial para garantir segurança, 
privacidade e controle ao acesso de usuários. 
 
Por fim, é importante destacar que autenticação por token (como JWT) é stateless, ou 
seja, o servidor não precisa manter uma sessão. Isso torna a aplicação mais 
escalável, especialmente quando há múltiplos servidores ou microsserviços. Porém, 
tokens devem ser protegidos e armazenados com cuidado no front-end — geralmente 
em memória ou localStorage com medidas de segurança contra ataques como XSS. 
 
A implementação da autenticação e login não apenas permite controlar o acesso dos 
usuários, como também cria a base para funcionalidades mais avançadas, como 
autorização por níveis (admin, usuário, convidado), reset de senha, verificação por e-
mail e muito mais. É um dos pilares da construção de sistemas seguros e confiáveis 
no desenvolvimento backend. 
 
 
 
 
Todos os materiais didáticos apresentados nesta plataforma são protegidos por direitos autorais de propriedade da Universidade Veiga 
de Almeida e do Centro Universitário Jorge Amado. Qualquer uso não autorizado, reprodução ou distribuição (incluindo o upload para 
sites) são estritamente proibidos e sujeitos às penalidades legais aplicáveis. Todos os direitos são reservados à UVA & Unijorge. 
Tema 3 
Boas práticas de segurança e validação de dados 
 
 
Como evitar que aplicações web se tornem vulneráveis 
a ataques ou falhas, assegurando que os dados 
recebidos sejam corretos, confiáveis e seguros? 
 
No desenvolvimento de aplicações web modernas, a segurança não pode ser um 
detalhe deixado para o fim do projeto. Desde as primeiras rotas criadas até o 
armazenamento final dos dados, cada etapa envolve riscos que, se ignorados, podem 
expor usuários, comprometer a integridade das informações e até permitir que 
sistemas inteiros sejam explorados por pessoas mal-intencionadas. Por isso, a prática 
da validação de dados e aplicação de medidas de segurança é um componente 
essencial no desenvolvimento de APIs robustas e confiáveis. 
 
Ao pensar em segurança de APIs, um dos primeiros pontos é entender é que nunca 
se deve confiar cegamente em dados externos. Isso significa que qualquer entrada 
vinda do cliente — como formulários, parâmetros de URL ou dados JSON no corpo da 
requisição — deve ser verificada, validada e tratada com rigor. 
 
Observação 
Falhas nesse processo podem abrir espaço para injeção de código, acesso 
indevido, corrupção de banco de dados, entre outros problemas. 
 
Um exemplo clássico de risco é o de inserção de script malicioso, 
conhecido como cross-site scripting (XSS), quando o usuário envia um 
código como alert('ataque') em um campo de formulário, 
esperando que ele seja executado posteriormente na tela de outro usuário. 
 
Outro problema comum é a injeção de comandos no banco de dados, 
algo menos comum em bancos NoSQL, mas ainda possível, 
principalmente quando dados são passados diretamente para consultas, 
sem validação. 
 
No contexto de uma aplicação em Node.js com Express e TypeScript, a validação 
pode ser feita com a ajuda de bibliotecas como joi, zod ou express-validator. 
 
A seguir, apresentamos as etapas necessárias à utilização do zod, uma biblioteca 
moderna e muito prática para tipar e validar dados ao mesmo tempo. 
 
 
 
Todos os materiais didáticos apresentados nesta plataforma são protegidos por direitos autorais de propriedade da Universidade Veiga 
de Almeida e do Centro Universitário Jorge Amado. Qualquer uso não autorizado, reprodução ou distribuição (incluindo o upload para 
sites) são estritamente proibidos e sujeitos às penalidades legais aplicáveis. Todos os direitos são reservados à UVA & Unijorge. 
 
1. Instale com: 
 
 
npm install zod 
 
 
Considere a construção de uma API de cadastro de usuários. 
 
2. A seguir, será criado um esquema de validação para o corpo da requisição de 
registro: 
 
 
import { z } from 'zod' 
 
const esquemaUsuario = z.object({ 
 nome: z.string().min(3, 'O nome deve ter no mínimo 3 caracteres'), 
 email: z.string().email('E-mail inválido'), 
 senha: z.string().min(6, 'A senha deve ter no mínimo 6 caracteres') 
}) 
 
 
3. Pode-se usar esse esquema dentro da rota de cadastro para garantir que os 
dados recebidos estejam corretos: 
 
 
import express from 'express' 
import { esquemaUsuario } from './schemas/usuario' 
 
const app = express() 
app.use(express.json()) 
 
app.post('/registro', (req, res) => { 
 const validacao = esquemaUsuario.safeParse(req.body) 
 if (!validacao.success) { 
 return res.status(400).json({ 
 erro: 'Dados inválidos', 
 detalhes: validacao.error.format() 
 }) 
 } 
 
 const { nome, email, senha } = validacao.data 
 // continuar com o salvamento seguro dos dados 
 res.status(201).json({ mensagem: 'Usuário validado com sucesso!' }) 
}) 
 
 
Esse tipo de validação previne erros lógicos e ataques. Além disso, retorna 
mensagens claras ao usuário, promovendo uma boa experiência. 
 
 
 
 
Todos os materiais didáticos apresentados nesta plataforma são protegidos por direitos autorais de propriedade da Universidade Veiga 
de Almeida e do Centro Universitário Jorge Amado. Qualquer uso não autorizado, reprodução ou distribuição (incluindo o upload para 
sites) são estritamenteproibidos e sujeitos às penalidades legais aplicáveis. Todos os direitos são reservados à UVA & Unijorge. 
Segurança, porém, vai além da validação de entrada: também envolve proteger o 
acesso às rotas e os dados em repouso. Isso inclui as implementações a seguir: 
 
• Autenticação. 
• Controle de permissões (ex: usuários admin vs. comuns). 
• Uso de HTTPS para evitar interceptações de dados. 
• Criptografia de senhas com bcrypt. 
• Tokenização e renovação segura de sessões com JWT. 
• Proteção contra CORS (Cross-Origin Resource Sharing). 
 
Um ponto crítico é a proteção contra requisições não autorizadas ou malformadas. 
Para isso, além da autenticação, pode-se utilizar middleware de segurança. 
 
A seguir, um exemplo de proteção contra chamadas de origens não confiáveis. 
 
 
import cors from 'cors' 
 
app.use(cors({ 
 origin: ['https://meusite.com'], // apenas seu front-end autorizado 
 methods: ['GET', 'POST', 'PUT'], 
 allowedHeaders: ['Content-Type', 'Authorization'] 
})) 
 
 
Além disso, devemos sempre evitar o envio de dados sensíveis em respostas da 
API. 
 
Por exemplo, ao retornar um objeto de usuário, nunca envie a senha criptografada, 
mesmo que esteja segura. Em vez disso, apenas os campos públicos devem ser 
enviados, conforme apresentado a seguir: 
 
 
res.json({ 
 nome: usuario.nome, 
 email: usuario.email 
}) 
 
 
Outro exemplo é o tratamento centralizado de erros. 
 
Criar um middleware para capturar e formatar erros evita vazamentos de mensagens 
sensíveis e melhora a experiência geral, conforme observamos a seguir: 
 
 
app.use((err, req, res, next) => { 
 console.error('Erro interno:', err) 
 res.status(500).json({ erro: 'Erro interno do servidor.' }) 
}) 
 
 
 
Todos os materiais didáticos apresentados nesta plataforma são protegidos por direitos autorais de propriedade da Universidade Veiga 
de Almeida e do Centro Universitário Jorge Amado. Qualquer uso não autorizado, reprodução ou distribuição (incluindo o upload para 
sites) são estritamente proibidos e sujeitos às penalidades legais aplicáveis. Todos os direitos são reservados à UVA & Unijorge. 
 
Ao aplicar essas práticas, teremos a garantia de que a aplicação esteja preparada 
para os desafios reais da internet. 
 
Em um sistema em produção, os dados dos usuários são um ativo valioso, e 
qualquer descuido pode comprometer a confiança no serviço. 
 
Um simples erro de validação pode permitir, por exemplo, que um usuário envie um 
número no qual deveria haver um e-mail, quebrando o sistema ou permitindo 
exploração. 
 
Por fim, um bom desenvolvedor backend deve ser, acima de tudo, cuidadoso com os 
dados que processa. Validação e segurança devem estar presentes desde os 
primeiros endpoints. Adotar ferramentas de validação, criptografia, autenticação e 
tratamento de erros forma um ciclo de boas práticas, que, quando aplicado 
corretamente, resulta em sistemas mais seguros, estáveis e confiáveis. 
 
 
 
Vídeo 
 
Para saber mais, assista ao vídeo publicado na unidade da disciplina no 
Ambiente Virtual de Aprendizagem. 
 
 
 
 
Todos os materiais didáticos apresentados nesta plataforma são protegidos por direitos autorais de propriedade da Universidade Veiga 
de Almeida e do Centro Universitário Jorge Amado. Qualquer uso não autorizado, reprodução ou distribuição (incluindo o upload para 
sites) são estritamente proibidos e sujeitos às penalidades legais aplicáveis. Todos os direitos são reservados à UVA & Unijorge. 
Encerramento 
 
 
Como armazenar e recuperar dados de forma flexível e 
escalável? 
 
A flexibilidade no armazenamento de dados é fundamental em aplicações que 
evoluem rapidamente, com mudanças frequentes na estrutura das informações. O 
MongoDB, como banco de dados NoSQL, permite trabalhar com documentos no 
formato JSON, no qual cada "registro" pode conter diferentes campos e tipos de 
dados. Isso elimina a necessidade de esquemas fixos, comuns em bancos relacionais, 
e torna mais simples lidar com dados variados. Além disso, o MongoDB é escalável 
horizontalmente, ou seja, pode ser distribuído em vários servidores para suportar 
grandes volumes de acesso. Dessa forma, será possível criar APIs modernas, rápidas 
e adaptáveis ao crescimento da aplicação. 
 
De que forma podemos garantir que apenas usuários 
autorizados acessem determinadas funcionalidades? 
 
Para garantir que apenas usuários autorizados tenham acesso a funcionalidades 
específicas de uma aplicação, implementamos mecanismos de autenticação. O 
processo geralmente começa com o cadastro do usuário, no qual a senha é protegida 
por meio de criptografia (hash) utilizando bibliotecas como bcrypt. No momento do 
login as credenciais são verificadas e, se válidas, o sistema gera um token 
(normalmente JWT – JSON Web Token), que identifica o usuário autenticado. Esse 
token é enviado em requisições futuras e verificado por middlewares de segurança no 
backend, que controlam o acesso às rotas privadas. Essa estratégia permite 
autenticação sem manter sessões no servidor, tornando o sistema mais escalável. A 
autenticação segura é essencial para proteger dados pessoais e evitar que usuários 
não autorizados acessem informações confidenciais ou alterem dados de outros 
usuários. 
 
Como evitar que aplicações web se tornem vulneráveis 
a ataques ou falhas, assegurando que os dados 
recebidos sejam corretos, confiáveis e seguros? 
 
Evitar vulnerabilidades em aplicações web começa com a validação rigorosa dos 
dados recebidos do usuário. Nenhuma entrada deve ser considerada segura por 
padrão. Usar bibliotecas como zod, joi ou express-validator ajuda a garantir que os 
dados estejam no formato esperado e contenham apenas informações válidas, como 
e-mails corretos, senhas fortes e textos sem scripts maliciosos. Além disso, é 
importante aplicar práticas como criptografia de senhas, uso de HTTPS, controle de 
permissões e tratamento de erros para evitar vazamento de informações. Ao proteger 
rotas com autenticação e limitar o acesso com base no perfil do usuário, fortalecemos 
 
 
Todos os materiais didáticos apresentados nesta plataforma são protegidos por direitos autorais de propriedade da Universidade Veiga 
de Almeida e do Centro Universitário Jorge Amado. Qualquer uso não autorizado, reprodução ou distribuição (incluindo o upload para 
sites) são estritamente proibidos e sujeitos às penalidades legais aplicáveis. Todos os direitos são reservados à UVA & Unijorge. 
ainda mais a segurança da aplicação. Tudo isso contribui para a integridade dos 
dados, a confiança do usuário e o bom funcionamento do sistema, mesmo em 
situações de uso indevido ou tentativas de invasão. 
 
 
Resumo da Unidade 
 
Este tema aprofunda o conhecimento sobre desenvolvimento de aplicações backend 
por meio de integração com bancos de dados NoSQL, como o MongoDB, e a 
implementação de autenticação de usuários e práticas essenciais de segurança. 
Inicialmente, são apresentados os conceitos e vantagens dos bancos NoSQL em 
relação aos modelos relacionais, destacando sua flexibilidade, escalabilidade e 
estrutura orientada a documentos. Em seguida, explora-se a autenticação segura de 
usuários com criptografia de senhas utilizando bcrypt e geração de tokens JWT para 
controle de acesso a rotas protegidas. Por fim, a unidade enfatiza a importância da 
validação de dados e das boas práticas de segurança no backend, como o uso de 
middlewares, tratamento de erros, proteção contra falhas comuns e blindagem da API 
contra dados maliciosos. Esses conhecimentos são fundamentais para construir 
sistemas robustos, seguros e preparados para o ambiente real de produção. 
 
 
Referências da Unidade 
 
• ALVES, W. P. Projetos de sistemas web: conceitos, estruturas, criação de 
banco de dados e ferramentas de desenvolvimento. São Paulo: Saraiva, 
2015. E-book. ISBN: 9788536532462. 
• FREITAS, P. H. C.; BIRNFELD, K.; SARAIVA, M. O.et al. Programação back 
end III. Porto Alegre: Grupo A, 2021. E-book. ISBN: 9786581492274. 
• OLIVEIRA, C. L. V.; ZANETTI, H. A. P. Javascript 
descomplicado: programação para web, iot e dispositivos móveis. São Paulo: 
Saraiva, 2020. E-book. ISBN: 9788536533100. 
 
 
Para aprofundar e aprimorar os seus conhecimentos sobre os assuntos 
abordados nessa unidade, não deixe de consultar as referências 
bibliográficas básicas e complementares disponíveis no plano de ensino 
publicado na página inicial da disciplina.

Mais conteúdos dessa disciplina