Alura > Cursos de Front-end > Cursos de React > Conteúdos de React > Primeiras aulas do curso React: implementando técnicas seguras de autenticação

React: implementando técnicas seguras de autenticação

Entendendo o que é autenticação - Apresentação

Apresentando o instrutor e o curso

Olá, estudante da Alura! Meu nome é Pedro Celestino de Mello, sou instrutor de front-end na Alura.

Audiodescrição: Pedro é um homem branco, com cabelos e barba escuros. Ele está em um ambiente iluminado pelas cores azul e rosa e veste roupas pretas.

Seja bem-vindo a mais um curso de React na plataforma da Alura. Neste curso, queremos propor uma reflexão: alguma vez já nos perguntamos como implementar um fluxo de autenticação e autorização completo em uma aplicação React? Além disso, já nos questionamos sobre a segurança das informações ao fazer um curso ou consumir algum conteúdo? Por exemplo, devemos armazenar dados como um cookie ou em local storage? Como garantir que o usuário não seja deslogado constantemente?

Introduzindo o guia de autenticação

Estamos aqui para responder a todas essas perguntas neste curso de autenticação. Vamos chamá-lo de guia de autenticação em aplicações modernas com React.

Olá! Este curso está repleto de conteúdo, pois vamos implementar logins básicos, como os que estão sendo exibidos agora na tela do projeto CodeConnect. Posteriormente, exploraremos mais detalhadamente o projeto CodeConnect. Teremos autenticação com login e senha, que está sendo demonstrada na tela, e também autenticação com redes sociais, utilizando, por exemplo, o Google OAuth. Vamos entender o que é o OAuth, como funciona e por que esse novo protocolo impactou significativamente o mundo do desenvolvimento web.

Preparando para o curso avançado

Faremos a configuração na plataforma Google Cloud para acessar a API e realizar essa autenticação. Este curso é mais avançado, portanto, é necessário que já tenhamos conhecimento prévio sobre o funcionamento do React, tipagens com TypeScript e os hooks mais comuns. A parte de estilização e criação de componentes será abordada de forma breve, pois muitos dos códigos de componentes e do Tailwind já estarão prontos. Nosso foco será nos fluxos, validações e, principalmente, na segurança, persistência e vulnerabilidades.

Explorando autenticação e segurança

Vamos começar aprendendo sobre autenticação: o que é, como funciona e sua importância. Em seguida, teremos uma parte específica sobre vulnerabilidades e segurança, que é o diferencial deste curso da Alura. Preparem-se, pois temos muito código para escrever juntos. Então, vamos lá, estudantes!

Entendendo o que é autenticação - Aprendendo sobre os fundamentos de autenticação

Introduzindo a autenticação em projetos React

Antes de começarmos a implementar a parte de autenticação, ou seja, o login e registro dentro da aplicação do CodeConnect, é importante entender os fundamentos da autenticação em projetos React e, de maneira geral, qual é a finalidade da autenticação e como prevenir alguns problemas. Vamos dividir essa discussão em dois momentos: primeiro, abordaremos a autenticação em si; depois, discutiremos os problemas de segurança que precisamos considerar ao trabalhar com autenticação.

Começando pela autenticação de forma simples, estamos verificando a identidade de uma pessoa usuária para que ela possa acessar o site, no caso, a aplicação do CodeConnect. Fazendo uma analogia com a vida real, imagine uma festa onde o acesso é garantido por uma pulseira. Ao receber um convite para a festa, a pessoa faz uma verificação ao chegar, e se possui a pulseira, o acesso é liberado. Caso contrário, o acesso é negado. No mundo dos desenvolvedores, ao criar uma conta em um site, fornecemos informações e, ao acessar o site, precisamos fornecer credenciais, geralmente um e-mail e uma senha. Posteriormente, discutiremos o login social utilizando OAuth, mas, por ora, focaremos no uso de e-mail e senha. O e-mail é fácil de obter, mas a senha funciona como a pulseira, sendo o diferencial para validar o acesso.

Diferenciando autenticação e autorização

Além disso, é comum confundir autenticação com autorização. A autenticação verifica quem somos ao fazer login e interagir com o site. O objetivo é identificar a pessoa que está acessando. A autorização, por outro lado, é uma segunda etapa. Usando novamente a analogia da festa, ao entrar com a pulseira, fazemos a autenticação na entrada. Se temos uma pulseira de acesso geral, não podemos acessar áreas VIP, pois não temos autorização. Pessoas com pulseira VIP têm autorização para acessar tanto áreas normais quanto VIP.

No contexto de desenvolvimento, ao acessar um site, se queremos editar um perfil ou acessar uma dashboard específica, precisamos de autorização no perfil. Autenticação e autorização são conceitos diferentes que trabalham juntos. A autenticação não depende da autorização, mas a autorização requer que a autenticação tenha sido realizada previamente.

Explorando abordagens de autenticação

Em projetos com múltiplas etapas, conciliamos a necessidade de autorização específica para determinados acessos na aplicação. Existem três abordagens principais para lidar com autenticação e verificação de autorizações em 2025. Vamos trabalhar com a abordagem híbrida, mas explicaremos rapidamente as três. A primeira, talvez a mais conhecida, é a utilização de um token JWT (JSON Web Token). Esse token é um objeto JSON que contém informações seguindo um padrão, geralmente o padrão do Google JWT. Ele é stateless (sem estado) e escalável, permitindo incluir informações sem necessidade de consulta ao banco de dados, pois é gerenciado via JavaScript e navegador.

Por conta de o JWT lidar exclusivamente com a parte de JavaScript, é mais difícil revogar o acesso. Uma vez que o token é válido para autenticação e autorização dentro do site, torna-se complicado realizar a revogação desse token. Além disso, ele é vulnerável a ataques do tipo XSS (Cross-Site Scripting). Esse tipo de ataque ocorre quando uma pessoa mal-intencionada utiliza informações do token que estão expostas de alguma forma. Se o token não for armazenado corretamente, fica suscetível a acessos não autorizados.

Utilizando cookies para autenticação

Temos também a seção com cookies, que é uma abordagem simples e fácil de implementar. Utilizamos o próprio cookie do navegador, o que nos afasta um pouco do JavaScript e do JWT, passando a depender dos navegadores. Sempre que mudamos de navegador, isso também acontece com o JWT. Em seções diferentes, um novo cookie é armazenado. Os cookies se popularizaram, e agora é obrigatório ter um aviso explicando que o site guarda tokens de cookies. Existe até um meme em que um garçom oferece um biscoito, simbolizando o cookie, ao acessar um site.

Com a popularização dos cookies e a forma aberta como são trabalhados, eles acabam sendo vulneráveis. Apesar de terem segurança contra ataques XSS, utilizando protocolos HTTP only para assegurar que vêm da mesma origem, é fácil acessar informações por meio dos cookies. Eles são arquivos pequenos e fáceis de acessar. Se não houver segurança adequada ou se informações forem colocadas de forma errada, isso pode se tornar um problema. Os cookies são stateful, ou seja, precisam ser atualizados sempre que há uma alteração no estado, diferentemente do JWT, que possui um tempo de expiração definido. O armazenamento em cookies é menor comparado ao Session Storage e Local Storage, o que limita a escalabilidade dependendo da quantidade de informações que queremos armazenar.

Combinando JWT e cookies na abordagem híbrida

A abordagem híbrida combina o melhor dos dois mundos: o JWT e a sessão em cookies. Unimos a escalabilidade stateless do JWT com a facilidade de revogação e proteção contra ataques XSS e CSRF (Cross-Site Request Forgery). Essa implementação previne ataques comuns e problemas de autenticação e vazamento de dados. No entanto, a desvantagem é que a implementação é mais complexa, exigindo atenção em diversos momentos. Algumas funcionalidades podem parar de funcionar até ajustarmos os níveis de autorização e requisição.

O objetivo é construir essa parte juntos, entendendo cada ponto ao preparar nosso projeto para utilizar essas abordagens. Vamos entender mais sobre esse fluxo. Ao fazer login, o servidor gera dois tokens: o access token, que emula um JWT e é armazenado na memória da aplicação (por exemplo, no React Context), e o refresh token, que permite validar novamente os dados de acesso após um tempo determinado. Podemos definir o tempo de expiração do refresh token conforme desejarmos.

Implementando o fluxo de tokens

A cada requisição, enviamos o access token. Quando ele expira, utilizamos o refresh token para renová-lo. Caso o refresh token expire, é necessário fazer um novo login para renová-lo. O access token tem um período de tempo menor e, ao expirar, verifica se o refresh token ainda é válido para continuar a atualização. O refresh token será HTTP only e salvo em cookie, contendo informações simples, sem expor dados importantes que estarão no access token, dentro de uma camada de segurança na aplicação.

Com isso, resolvemos dois problemas de segurança, que serão discutidos em detalhes: XSS e CSRF. Vamos entender mais sobre esses problemas de segurança para dar sequência ao fluxo de implementação de login no CodeConnect. Esperamos continuar nesse caminho de aprendizado.

Entendendo o que é autenticação - Princípios de vulnerabilidade e segurança

Abordando vulnerabilidades e segurança em autenticação

Agora, vamos abordar a questão da vulnerabilidade e segurança, que são os dois pilares principais quando tratamos de autenticação em projetos, especialmente em projetos voltados para o React. No vídeo anterior, discutimos as diferenças entre autenticação e autorização, além de abordarmos as abordagens mais utilizadas, como JWT, sessão In-Context ou a abordagem híbrida, que é a mais recomendada atualmente no desenvolvimento moderno para a web.

Também mencionamos algumas siglas que começaremos a explorar agora, iniciando pelo XSS, o temido Cross-Site Scripting. Basicamente, o XSS é um ataque em que uma pessoa maliciosa utiliza código JavaScript malicioso para acessar informações da nossa aplicação web. Um exemplo seria um espião escondido em algum comentário JavaScript.

Explorando ataques XSS e suas consequências

Vamos supor que estamos utilizando JWT para autenticação no nosso servidor. Uma pessoa maliciosa pode inspecionar o código, ver as chamadas feitas pelo navegador e perceber que há um arquivo acessível que se comunica com algumas APIs. Por ser um arquivo JavaScript, como o JSON, é possível inserir scripts nele. Assim, o JSON Web Token pode ser comprometido com código JavaScript malicioso, que pode derrubar o site, roubar informações de usuários ou inserir bots e spiders que leem o código da aplicação e enviam para terceiros ou armazenam em algum local. Essa é uma falha de segurança grave, especialmente em autenticação, e é crucial que tratemos esse problema para evitar falhas durante a navegação.

O fluxo detalhado seria: o hacker cria um script malicioso e o insere em algum comentário do site. Se o site renderiza sem sanitização, o script é executado no navegador da vítima. Nesse momento, o hacker ainda não tem acesso a informações. Quando a pessoa faz login, os tokens podem ser roubados, e as informações de login e senha podem ser encaminhadas para o hacker.

Participando de CTFs e a importância da sanitização

Participamos de alguns CTFs (Capture the Flag) na área de segurança, e esse é um dos ataques mais comuns nos primeiros níveis, o ataque XSS. Por já termos explorado o outro lado e estudado segurança, sabemos o perigo de liberar acesso para uma pessoa mal-intencionada introduzir um JavaScript malicioso através de um token circulando no site. Além de cuidar da autenticação e autorização dos tokens, é necessário sanitizar o código JavaScript, especialmente em ambientes de produção, pois ao inspecionar um código, podemos ver detalhes como a cor do botão e tokens. Com conhecimento avançado em engenharia reversa, é possível encontrar brechas, principalmente em arquivos que transitam sem segurança, como o JWT.

Entendendo o ataque CSRF e suas implicações

Agora, vamos falar sobre o CSRF. Sempre que aparecerem as siglas, utilizaremos as siglas em vez de repetir o nome completo, para facilitar o entendimento. O Cross-Site Request Forgery ocorre quando há exposição de dados e o hacker tem acesso à informação. Se houver uma brecha na aplicação para injetar um script sem autorização do usuário, como para fazer uma transferência ou aceitar uma compra, abre-se uma brecha para um ataque CSRF.

Se uma pessoa maliciosa tem as informações e os tokens, e não há um trabalho de autorização, como o uso de Refresh Token e Access Token que expiram e precisam ser renovados, garantimos que esse tipo de problema de autorização não ocorra. No entanto, é comum que informações vazem, como tokens de usuário, e sejam feitas requisições sem verificação prévia da autorização do usuário.

Exemplificando o risco de vazamento de informações

Por exemplo, um usuário logado no site A pode estar fazendo uma compra. Imagine uma rede social de vídeos famosa, cujo símbolo é musical. Se o usuário acessa essa rede social e vê um vídeo sobre um patinete a um preço irrisório, ao clicar, as informações do site A para o site B podem vazar se não houver tratamento adequado. Isso pode incluir informações como "vim do site A e estou vindo para o site B através do anúncio XYZ".

Ao acessar um site B, podemos nos deparar com uma interface que imita outro site, fazendo parecer que faz parte do site A. Por exemplo, um checkout para comprar um patinete a um preço muito baixo. Ao inserir informações pessoais, dados de pagamento e endereço, sem verificar a validade do site, corremos o risco de expor nossos dados. Com o avanço das IAs e a clonagem de interfaces, torna-se cada vez mais difícil identificar fraudes. Às vezes, erros sutis, como caracteres de um alfabeto que se assemelham ao nosso alfabeto comum, podem passar despercebidos. Esses caracteres podem ser quase idênticos aos nossos, dificultando a identificação a olho nu, a menos que sejamos especialistas em design.

Implementando estratégias de segurança no desenvolvimento

Ao compartilhar informações no site B, estando logados no site A, essas informações podem ser armazenadas e utilizadas de forma maliciosa. O CUC, sendo stateful (com estado), atualiza-se a cada alteração de estado. Assim, ao passar informações para o site B, estamos gerando uma requisição de autorização. O site A, ao receber essas informações, pode acreditar que fomos nós que autorizamos ações como transferências bancárias ou compras, já que inserimos nossos dados sem verificar a legitimidade do site.

É importante, ao desenvolver uma parte de login, considerar estratégias de segurança desde o início. Para garantir uma estratégia de segurança completa, nosso Access Token será armazenado na memória interna do React, através do Context, com duração de 15 minutos. Ele será utilizado em todas as requisições para a API. Nossa proteção contra XSS (Cross-Site Scripting) não permitirá que o Access Token persista após um reload na aplicação. Após o reload, o Access Token será gerado novamente através do nosso Refresh Token, que será armazenado em um cookie do tipo HTTP only, permitindo acessos apenas através do domínio em que estamos trabalhando. A duração do Refresh Token será de 7 dias.

Utilizando autenticação social e reforçando a segurança

Em nosso projeto, utilizaremos autenticação através de login social, como o OAuth com o Google, facilitando o login em um segundo momento. O Refresh Token será usado apenas para renovar o Access Token. Essa abordagem protege contra ataques XSS, pois o Refresh Token não será acessível. Além disso, o React escapará automaticamente as variáveis nas requisições, e os headers das requisições serão customizados. Para produção, forçaremos o uso de HTTPS, garantindo uma camada adicional de segurança. Utilizaremos cookies com a política same site, permitindo acesso apenas se estivermos no mesmo domínio, como no CodeConnect. Assim, outras aplicações abertas no navegador não terão acesso ao cookie com as informações do Refresh Token.

Compreendemos, portanto, a importância de considerar vulnerabilidades e segurança no desenvolvimento de logins. Vamos agora para o nosso código, entender a estrutura e o que precisamos implementar para o nosso login. Vejo vocês na sequência.

Sobre o curso React: implementando técnicas seguras de autenticação

O curso React: implementando técnicas seguras de autenticação possui 297 minutos de vídeos, em um total de 43 atividades. Gostou? Conheça nossos outros cursos de React em Front-end, ou leia nossos artigos de Front-end.

Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:

Aprenda React acessando integralmente esse e outros cursos, comece hoje!

Conheça os Planos para Empresas