NestJS: protegendo rotas com Guards
NestJS: protegendo rotas com Guards
E aí, pessoal! Tudo bem com vocês? Hoje quero compartilhar algo super importante para quem está desenvolvendo aplicações web: como proteger nossas rotas no NestJS usando Guards. Vamos juntos entender passo a passo como fazer isso de forma simples e eficaz. Preparados? Então vamos nessa!
Por que proteger as rotas é tão importante?
Imagina só: você cria uma aplicação incrível, cheia de funcionalidades legais, mas deixa as portas abertas para qualquer um entrar. Não dá, né? Assim como em uma casa, precisamos garantir que apenas pessoas autorizadas tenham acesso a certas áreas da nossa aplicação. É aqui que o NestJS nos ajuda com os Guards, que são como os seguranças das nossas rotas.
Quer conhecer mais sobre o NestJS?
Se você ainda não conhece o NestJS ou quer se aprofundar um pouco mais no framework, recomendo dar uma olhada nesse vídeo:
O que são Guards no NestJS?
Os Guards são classes que decidem se uma requisição pode ou não prosseguir para o para o controller da rota. Eles verificam se o usuário tem permissão para acessar aquele recurso. É como se eles perguntassem: "Você está autorizado a entrar aqui?" Se a resposta for sim, a requisição segue; se não, ela é bloqueada.
Guards vs. Middleware
Talvez você já tenha usado middlewares para autenticação, mas os Guards têm uma vantagem: eles conseguem acessar o contexto específico da rota que está sendo chamada. Isso significa que eles sabem exatamente qual controlador e qual método estão sendo acessados, permitindo uma lógica de autorização mais precisa.
Criando um AuthGuard no NestJS
Vamos colocar a mão na massa e criar um Guard que verifica se o usuário está autenticado antes de acessar certas rotas.
Configurando a estratégia JWT
Primeiro, precisamos configurar a estratégia de autenticação usando JWT (JSON Web Token). Vamos criar um arquivo chamado
jwt-strategy.ts
e começar a implementar nossa estratégia.import { Injectable } from '@nestjs/common'; import { PassportStrategy } from '@nestjs/passport'; import { Strategy, ExtractJwt } from 'passport-jwt'; @Injectable() export class JwtStrategy extends PassportStrategy(Strategy) { constructor() { super({ jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), secretOrKey: /* sua chave privada */, algorithms: ['RS256'], }); } async validate(payload: any) { // validação do token return { userId: payload.sub }; } }
Aqui, estamos definindo de onde o token será extraído (normalmente do headerAuthorization
), qual é a chave privada para validar o token e qual algoritmo estamos usando. No métodovalidate
, podemos verificar se o token possui as informações que esperamos.
Registrando a estratégia no módulo
Não esqueça de registrar a estratégia no módulo da sua aplicação:
import { JwtStrategy } from './jwt-strategy'; @Module({ providers: [JwtStrategy], }) export class AppModule {}
Criando o AuthGuard
Agora, vamos criar o Guard que vai usar essa estratégia. Crie um arquivo
jwt-auth.guard.ts
:import { Injectable } from '@nestjs/common'; import { AuthGuard } from '@nestjs/passport'; @Injectable() export class JwtAuthGuard extends AuthGuard('jwt') {}
Aqui, estamos estendendo oAuthGuard
do Passport e especificando que vamos usar a estratégia 'jwt' que criamos.
Protegendo uma rota com o Guard
Vamos supor que temos um controlador para criar perguntas, e queremos que apenas usuários autenticados possam acessar essa rota.
import { Controller, Post, UseGuards } from '@nestjs/common'; import { JwtAuthGuard } from './jwt-auth.guard'; @Controller('questions') export class QuestionsController { @Post() @UseGuards(JwtAuthGuard) createQuestion() { // lógica para criar uma pergunta return { message: 'Pergunta criada com sucesso!' }; } }
Com o decorador@UseGuards(JwtAuthGuard)
, estamos protegendo a rotacreateQuestion
. Agora, se alguém tentar acessá-la sem um token válido, receberá um erro 401 Unauthorized.
Testando nossa rota protegida
- Primeiro, faça uma requisição de login para obter o token JWT.
- Depois, tente acessar a rota protegida sem o token e veja que receberá um erro de autorização.
- Por fim, inclua o token no header
Authorization: Bearer seu_token_aqui
e tente novamente. Agora, a requisição deve ser bem-sucedida.
Dica para facilitar os testes
Se você quiser automatizar esse processo, pode armazenar o token em uma variável e referenciá-lo nas suas requisições. Assim, toda vez que o token for atualizado, suas requisições usarão o novo valor automaticamente.
Validando o payload do token
É importante garantir que o token contém as informações que esperamos. Podemos usar uma biblioteca como o
zod
para validar o payload.import { z } from 'zod'; async validate(payload: any) { const tokenSchema = z.object({ sub: z.string().uuid(), }); return tokenSchema.parse(payload); }
Se o token não tiver osub
(que é o ID do usuário), a validação falhará e o acesso será negado.
Entendendo melhor o que acontece nos bastidores
Quando usamos o JwtAuthGuard, ele verifica se o token é válido usando a estratégia que configuramos. Se o token for válido e o payload passar na validação, o usuário é considerado autenticado e pode acessar a rota.
E se quisermos proteger todas as rotas de um Controller?
Podemos aplicar o Guard no nível do controller:
@UseGuards(JwtAuthGuard) @Controller('questions') export class QuestionsController { // todas as rotas aqui estarão protegidas }
Dessa forma, todas as rotas dentro desse controlador exigirão autenticação.
Conclusão
E aí, gostou desse conteúdo sobre Guards no NestJS? Se você está animado para continuar sua jornada e quer ir muito além, tenho uma recomendação que vai transformar sua forma de desenvolver aplicações backend!
Na Formação Node.js da Rocketseat, você vai viver uma experiência hands-on de verdade, com o nosso incrível professor Diego Fernandes, que é uma verdadeira referência no mercado de tecnologia! Diego é especialista em JavaScript, apaixonado por codar e sempre traz uma didática super prática e envolvente, que faz a gente querer aprender mais a cada aula!
Mas não para por aí! Além de aulas com uma didática única, você vai colocar a mão na massa em projetos reais que simulam desafios do dia a dia das empresas, desenvolvendo aplicações que têm tudo a ver com as demandas do mercado atual. São mais de 8 projetos profissionais para você adicionar ao seu portfólio e impressionar os recrutadores!
Na Rocketseat, você não aprende sozinho. Além de todo esse conteúdo, você terá tutorias individuais, bate-papos em grupo sobre carreira e estudos, e o Café com os Instrutores, onde você troca ideias diretamente com especialistas. E ainda rola o Talent Space, uma semana de eventos para impulsionar sua carreira com empresas parceiras compartilhando dicas e vagas.
Então, o que você está esperando para se juntar a essa comunidade incrível e levar suas habilidades para o próximo nível? Vem fazer parte da Formação Node.js da Rocketseat e construir um portfólio que vai fazer brilhar os olhos dos recrutadores!
Vamos juntos nessa jornada? Te vejo lá!