Alura > Cursos de Programação > Cursos de Node.JS > Conteúdos de Node.JS > Primeiras aulas do curso Nodejs: Autenticação, Passport e OAuth 2.0

Nodejs: Autenticação, Passport e OAuth 2.0

Iniciando o projeto - Apresentação

Olá! Te desejo as boas-vindas ao curso de Autenticação OAuth com Node.js! Meu nome é Guilherme Lima e serei seu instrutor.

Audiodescrição: Guilherme é uma pessoa de pele clara, barba e cabelos curtos e escuros. Usa óculos de armação retangular na cor preta e veste uma camiseta verde. Ao fundo, uma parede azul com desenhos abstratos.

Vamos explorar o que aprenderemos neste curso!

Inicialmente, temos um site onde realizaremos o login. Nosso objetivo é criar uma estratégia de autenticação do zero, coletando informações de cadastro como nome, e-mail e senha, armazenando esses dados no banco de dados e, em seguida, realizando o login na aplicação.

Além disso, aprenderemos a proteger uma rota ou recurso da nossa aplicação utilizando middleware. Também implementaremos a autenticação OAuth com o GitHub. Assim, quando clicarmos no GitHub, seremos redirecionados para uma área exclusiva de membros da aplicação.

Por outro lado, se tentarmos acessar a área de membros diretamente, sem realizar a autenticação, veremos que o acesso não é permitido. Aprenderemos a configurar essa proteção e a gerenciar acessos de forma segura.

Estamos muito felizes em ter você aqui e esperamos que goste deste curso. Nos vemos em breve!

Iniciando o projeto - Projeto base

Vamos iniciar nossos estudos sobre autenticação e OAuth!

Preparando o ambiente

Temos um projeto base com algumas telas de login e cadastro. Nosso foco será na autenticação, por isso, vamos utilizar o Node.js. É essencial que você tenha o Node instalado em sua máquina.

Na atividade anterior, fornecemos um passo a passo do que é necessário: instalar o Node e o Docker. O Node será usado como nosso servidor e o Docker para executar nosso banco de dados MongoDB. Não se preocupe se você nunca usou o MongoDB, vamos simplificar sua utilização.

No meu computador, já tenho o Docker Desktop instalado e executando, assim como o Node. Podemos verificar as versões com os comandos node --version e docker --version. Aqui, estamos utilizando, respectivamente, as versões 20.12.2 e 26.0.0

Download do projeto base

Na sequência, é necessário fazer o download do projeto base, cujo link está na atividade de preparação do ambiente, anterior a este vídeo. Após fazer o download, vamos abri-lo.

Vamos nos concentrar em como carregar nosso projeto com Node.js. O projeto possui várias pastas: controllers, public, routes, util, views, entre outras. Vamos entender o funcionamento desse projeto.

O arquivo package.json lista as dependências necessárias. Temos o body-parser, connect-mongodb-session, ejs, express, e mongodb. Além do package.json, há um arquivo docker-compose.yml que carrega uma imagem do Docker com o MongoDB instalado.

Instalando as dependências do projeto

O primeiro comando a executar é para instalar as dependências em nossa máquina. Vamos executá-lo no terminal:

npm i

Isso instalará todas as dependências listadas no package.json e criará as pastas node_modules e package-lock.json.

Iniciando o banco de dados com Docker

Para executar nosso banco de dados no Docker pela primeira vez, utilizamos o seguinte comando:

docker-compose up -d --build

O -d significa que o comando não bloqueará o terminal, e o --build é usado apenas na primeira execução para construir a imagem. Depois, usaremos apenas docker-compose up -d.

Executando o servidor

Agora, com o banco de dados rodando no Docker e todas as dependências instaladas, vamos configurar o ambiente de desenvolvimento. O script nodemon app.js no package.json nos ajuda a executar o projeto. Para isso, executamos o seguinte comando:

npm run dev

Após executar, você verá a mensagem "Conectado com o MongoDB com sucesso". Nosso projeto está rodando na porta 3000. Você pode verificar isso acessando localhost:3000 no navegador.

Tela do projeto

O projeto está funcionando! Agora, vamos explorar o que ele faz. Temos telas de login e cadastro. No cadastro, você pode inserir nome, e-mail e senha. No entanto, ao clicar em criar, nada acontece porque ainda não configuramos isso no servidor. O mesmo ocorre na tela de login.

Nosso próximo passo é configurar a autenticação, criando um sistema de login com e-mail e senha para proteger rotas exclusivas para membros. Por exemplo, a rota /members deve ser acessível apenas para usuários autenticados.

Próximos passos

Na próxima etapa, vamos configurar a autenticação e garantir que apenas usuários registrados possam acessar áreas protegidas do nosso aplicativo.

Vamos começar a implementar essa funcionalidade!

Iniciando o projeto - Modelo de usuário

Nosso desafio agora é estruturar o banco de dados e o servidor para realizar o login e a autenticação!

Quando clicamos no link "Crie Seu Cadastro", somos direcionados para uma página onde coletamos informações como nome, e-mail e senha. Precisamos capturar essas informações do formulário, armazená-las no banco de dados e depois compará-las na tela de login. Essa estratégia de autenticação é conhecida como Basic OAuth (autenticação básica).

Primeiro, vamos estruturar os nossos dados. Queremos criar uma classe chamada de usuário que terá esses campos, para que, quando a pessoa clicar em "Criar", possamos usar essa estrutura para gravar as informações no banco de dados.

Criação da pasta models

No nosso projeto, vamos criar uma pasta chamada models para armazenar tudo relacionado ao banco de dados. Essa prática é comum em projetos com Node, Python, Django, Java, Spring, etc. Dentro da pasta models, criaremos um arquivo chamado User.js.

Podemos usar diferentes estratégias para comunicar nosso projeto Node.js com o banco de dados, como ORM (Object-Relational Mapping), Prisma, SQLite, entre outros. No entanto, nosso foco é a autenticação, não o ORM. Já temos uma pasta chamada util, que faz a conexão com o MongoDB que está rodando no Docker, tudo já configurado. Apenas precisamos utilizar esse banco de dados chamando o getDb.

Criação da classe User

Vamos criar uma classe User baseada nos dados do formulário (nome, e-mail e senha). Sempre que quisermos criar um novo usuário, usaremos essa estrutura.

A classe terá um construtor que recebe username, email e password, e atribui esses valores às propriedades da instância.

class User {
    constructor(username, email, password) {
        this.username = username;
        this.email = email;
        this.password = password;
    }

Criação do método save

Em seguida, precisamos criar um método responsável por salvar os dados no banco de dados. Vamos chamá-lo de save(). É importante notar que, sempre que salvamos no banco de dados, precisamos esperar que a execução desse método seja concluída, portanto, ele será um método assíncrono (async).

class User {
    constructor(username, email, password) {
        this.username = username;
        this.email = email;
        this.password = password;
    }

    async save() {
        
        }

Conexão com o Banco de Dados

Agora, vamos criar uma constante chamada getDb e atribuir a ela o resultado do require, apontando para o arquivo '../util/database'.

const getDb = require('../util/database')

class User {
    constructor(username, email, password) {
        this.username = username;
        this.email = email;
        this.password = password;
    }

    async save() {
        
        }

Inserção de dados na coleção users

Em seguida, dentro do método save(), criamos uma constante chamada db e atribuímos a função getDb().

Agora, sempre que alguém for salvar um novo usuário, vamos retornar db.collection('users').insertOne(this) para inserir o próprio objeto na coleção users.

Perceba que usamos essa instância para inserir o novo usuário na coleção users. Este nome de coleção no plural é uma prática comum para representar uma coleção de entidades.

const getDb = require('../util/database')

class User {
    constructor(username, email, password) {
        this.username = username;
        this.email = email;
        this.password = password;
    }

    async save() {
        const db = getDb()
        return db.collection('users').insertOne(this)
    }
}

Exportação do módulo

Por fim, precisamos exportar o módulo com module.exports = User.

const getDb = require('../util/database')

class User {
    constructor(username, email, password) {
        this.username = username;
        this.email = email;
        this.password = password;
    }

    async save() {
        const db = getDb()
        return db.collection('users').insertOne(this)
    }
}

module.exports = User

Conclusão e próximos passos

Dessa forma, nossa classe de usuário está estruturada e pronta para ser utilizada na aplicação, permitindo que salvemos novos usuários no banco de dados de maneira eficiente e organizada.

Quando o usuário preencher os campos de nome, e-mail e senha e clicar em "Criar", queremos usar essa estrutura para armazenar o usuário no banco de dados e, em seguida, permitir que ele faça login. É o que faremos a seguir!

Sobre o curso Nodejs: Autenticação, Passport e OAuth 2.0

O curso Nodejs: Autenticação, Passport e OAuth 2.0 possui 108 minutos de vídeos, em um total de 39 atividades. Gostou? Conheça nossos outros cursos de Node.JS em Programação, ou leia nossos artigos de Programação.

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

Aprenda Node.JS acessando integralmente esse e outros cursos, comece hoje!

Conheça os Planos para Empresas