• Venho observando a evolução da internet desde muito tempo atrás… Me lembro que lá pelos meados de 2003~2004, usávamos muito o Apache com o PHP como o serviço HTTP em servidores.

    Tive amigos que tiveram grandes sites, sites de humor, alguns de warez na época, quem nunca?

    A questão era, que na época dos primórdios da internet, as CPUs não eram tão avançadas assim, para você ter ideia, o link de um servidor dedicado (hoje chamados de bare-metal) era de 10mbps quando contratado no Brasil ou de 100mbps quando contratado fora, e era bem caro.

    Me lembro de um amigo ter descoberto o NGINX por volta de 2008, esse amigo meu já gerenciava um site de outro amigo que era um site famoso com humor e besteirol, mas que na época já recebia uma pancada de visitantes simultaneamente.

    Me recordo de que a única forma desse site conseguir ficar no ar e aguentar os horários de pico foi com essa descoberta e configuração do uso do NGINX ao invés do Apache.

    Não sei se vocês sabem, mas de acordo com o gráfico obtido no site W3Techs.com, mostra que apenas em 2019 o NGINX ultrapassou o Apache em uso de servidores web.

    Eu sei que depois que eu descobri a quantidade absurda de requisições por segundo que um proxy reverso igual o NGINX pode atingir, eu nunca mais consegui usar o Apache como servidor WEB. E acho que hoje em dia pouca gente deva usar né?

    Vou deixar aqui alguns links com testes de performance entre servidores web:
    https://www.site24x7.com/learn/web-server/apache-vs-nginx-web-server.html
    https://kinsta.com/pt/blog/nginx-vs-apache/

    Ou seja, escolha NGINX ao invés do Apache, especialmente para alta performance e eficiência, especialmente para sites com alto volume de acesso, com muito conteúdo estático.

  • Instalar o Node.js

    Antes de tudo, verifique se o Node.js está instalado:

    node -v

    Se não estiver, baixe e instale pelo site oficial https://nodejs.org

    Instalar o Node.js

    Crie uma nova pasta e inicie um projeto Node:

    mkdir hello-express
    cd hello-express
    npm init -y
    Instale o módulo Express

    Instale o framework Express com:

    npm install express
    
    Criar o arquivo do servidor
    // Importa o módulo Express (framework minimalista para Node.js)
    const express = require('express');
    
    // Cria uma instância da aplicação Express
    const app = express();
    
    /* 
      -------------------------------
      ROTAS HTTP NO EXPRESS
      -------------------------------
    
      O Express permite definir rotas usando métodos que correspondem
      aos principais verbos HTTP, como:
      
      - GET: usado para obter dados (ex: acessar uma página ou API)
      - POST: usado para enviar dados (ex: formulários, APIs)
      - PUT: usado para substituir dados existentes
      - PATCH: usado para atualizar parcialmente dados existentes
      - DELETE: usado para remover dados
      - ALL: usado para responder a *qualquer* tipo de requisição HTTP
    
      Cada rota segue o formato:
      
          app.METODO('CAMINHO', (req, res) => { ... })
      
      Onde:
        - req = objeto da requisição (request)
        - res = objeto da resposta (response)
    */
    
    /* 
      Rota GET para a raiz "/"
      Essa rota responde quando alguém acessa: http://localhost:3000/
    */
    app.get('/', (req, res) => {
      res.send('Hello World! (GET /)');
    });
    
    /*
      Rota POST para "/"
      Responde quando alguém envia dados (ex: via formulário ou API POST)
    */
    app.post('/', (req, res) => {
      res.send('Você fez uma requisição POST!');
    });
    
    /*
      Rota PUT para "/"
      Usada normalmente para atualizar *todo* um recurso existente
    */
    app.put('/', (req, res) => {
      res.send('Você fez uma requisição PUT!');
    });
    
    /*
      Rota PATCH para "/"
      Usada para atualizar *parte* de um recurso existente
    */
    app.patch('/', (req, res) => {
      res.send('Você fez uma requisição PATCH!');
    });
    
    /*
      Rota DELETE para "/"
      Usada para remover um recurso existente
    */
    app.delete('/', (req, res) => {
      res.send('Você fez uma requisição DELETE!');
    });
    
    /*
      Rota ALL para "/"
      Responde a *qualquer método HTTP*
      (GET, POST, PUT, DELETE, etc.) — é como um "coringa"
      Pode ser útil para criar middlewares ou respostas genéricas.
    */
    app.all('/all', (req, res) => {
      res.send(`Você acessou a rota ALL com o método: ${req.method}`);
    });
    
    /*
      Também é possível usar o caractere "*" para capturar qualquer rota
      que não exista (ex: erro 404 personalizado)
    */
    app.all('*', (req, res) => {
      res.status(404).send('Rota não encontrada!');
    });
    
    /*
      Inicia o servidor na porta 3000
      Quando o servidor estiver rodando, a mensagem abaixo será exibida no terminal.
    */
    app.listen(3000, () => {
      console.log('Servidor rodando em http://localhost:3000');
    });
    Executar o servidor

    No terminal, rode o comando:

    node server.js

    Você verá:

    Servidor rodando em http://localhost:3000

    Abra esse endereço no navegador, e verá: Hello World! (GET /)

  • Brinco com programação desde 2004 e o meu intuito com este blog não é nada muito sério e nem profissional. Eu quero apenas compartilhar qualquer coisa relacionada a tecnologia e programação com a humanidade. Estudar as métricas do Google Search Console e eventualmente algum SEO.

    Então, obrigado e seja bem-vindo(a)!

  • Nesse tutorial você vai aprender de forma prática como criar sistema que se autentica no OAuth do Google para ler e-mails usando o Gmail API.

    A API do Gmail é muito útil para a criação de aplicativos para poder identificar e-mails indesejados e também oferecer serviços em forma de SaaS para limpar caixas de entradas.

    Utilizaremos a seguinte stack nesse tutorial:

    • Frontend: Javascript (fetch + botão de login)
    • Backend: Nodejs usando o módulo Express
    • Biblioteca npm: googleapis
    • OAuth: Google Cloud Console (GCP)

    Criar as credenciais necessárias para autenticar no OAuth

    • Vá em https://console.cloud.google.com
    • Crie um novo projeto
    • Acesse Google Auth Platform → Clientes → Criar cliente

      Preencha o formulário, informando o tipo de aplicativo como Aplicativo da Web, dê um nome ao seu novo aplicativo, e em URIs de redirecionamento autorizados, informe http://localhost:4000/oauth/receive, que vai ser utilizado em nosso exemplo.

      Clique em Criar e no próximo popup, anote o ID do cliente (Client ID) e a Chave secreta do cliente (Client Secret), vamos precisar dessas informações adiante.
    • Acesse Google Auth Platform → Branding e preencha o nome do app, e-mail para suporte do usuário e dados do contado do desenvolvedor para iniciarmos os testes.

    Configurando o backend (Nodejs + Express)

    Instalar dependências

    Crie uma nova pasta para iniciar um novo projeto NodeJS.
    Abra o terminal ou o prompt de comando e digite o código abaixo.

    npm init -y
    npm install express express-session googleapis body-parser

    Estrutura de pastas do nosso projeto

    project/
    ├─ server.mjs
    ├─ tokens.json
    └─ public/
          └─ index.html
    Arquivo server.mjs

    Crie o arquivo server.mjs e altere a variável CLIENT_ID com o seu ID do cliente, e o CLIENT_SECRET com a Chave secreta do cliente

    import express from "express";
    import session from "express-session";
    import fs from "fs";
    import { google } from "googleapis";
    import bodyParser from "body-parser";
    
    const app = express();
    const PORT = 4000;
    
    const CLIENT_ID = "INSIRA_SEU_CLIENT_ID"; // Exemplo: 292545165314-jqgquadfjl5pjh53vbosj0k8djm91u6r.apps.googleusercontent.com
    const CLIENT_SECRET = "INSIRA_SEU_CLIENT_SECRET"; // Exemplo: GOCSPX-2rmk...(omitido)
    const REDIRECT_URI = "http://localhost:4000/oauth/receive";
    const SCOPES = ["https://www.googleapis.com/auth/gmail.readonly"];
    
    const oAuth2Client = new google.auth.OAuth2(CLIENT_ID, CLIENT_SECRET, REDIRECT_URI);
    
    app.use(express.static("public"));
    app.use(bodyParser.json());
    app.use(
        session({
            secret: "informar-string-aleatoria",
            resave: false,
            saveUninitialized: true,
        })
    );
    
    const TOKENS_FILE = "./tokens.json";
    let tokensDB = {};
    if (fs.existsSync(TOKENS_FILE)) {
        tokensDB = JSON.parse(fs.readFileSync(TOKENS_FILE));
    }
    
    function saveTokens() {
        fs.writeFileSync(TOKENS_FILE, JSON.stringify(tokensDB, null, 2));
    }
    
    app.get("/oauth/redir/:email", (req, res) => {
        const { email } = req.params;
    
        if (!email) return res.status(400).send("Email é obrigatório.");
        req.session.email = email;
    
        const authUrl = oAuth2Client.generateAuthUrl({
            access_type: "offline",
            scope: SCOPES,
            prompt: "consent",
        });
    
        res.json({ url: authUrl });
    });
    
    app.get("/oauth/receive", async (req, res) => {
        const code = req.query.code;
        const email = req.session.email;
        if (!code || !email) return res.send("Erro: sessão expirada ou código inválido.");
    
        const { tokens } = await oAuth2Client.getToken(code);
        tokensDB[email] = tokens;
        saveTokens();
    
        res.send(`
        <h2>Autorizado com sucesso!</h2>
        <p>Conta: ${email}</p>
        <a href="/">Voltar</a>
      `);
    });
    
    app.get("/emails/:email", async (req, res) => {
        const email = req.params.email;
        const tokens = tokensDB[email];
        if (!tokens) return res.status(400).send("Email não autorizado.");
    
        oAuth2Client.setCredentials(tokens);
        const gmail = google.gmail({ version: "v1", auth: oAuth2Client });
    
        try {
            const response = await gmail.users.messages.list({
                userId: "me",
                maxResults: 10,
            });
    
            const messages = response.data.messages || [];
            const messageData = [];
    
            for (const msg of messages) {
                const fullMsg = await gmail.users.messages.get({
                    userId: "me",
                    id: msg.id,
                });
    
                const headers = fullMsg.data.payload.headers;
                const subject = headers.find((h) => h.name === "Subject")?.value || "(Sem assunto)";
                const from = headers.find((h) => h.name === "From")?.value || "(Desconhecido)";
                messageData.push({ id: msg.id, subject, from });
            }
    
            res.json(messageData);
        } catch (err) {
            console.error(err);
            res.status(500).send("Erro ao listar emails");
        }
    });
    
    app.get("/email/:email/:id", async (req, res) => {
        const { email, id } = req.params;
        const tokens = tokensDB[email];
        if (!tokens) return res.status(400).send("Email não autorizado.");
    
        oAuth2Client.setCredentials(tokens);
        const gmail = google.gmail({ version: "v1", auth: oAuth2Client });
    
        try {
            const message = await gmail.users.messages.get({
                userId: "me",
                id,
                format: "full",
            });
    
            const body = message.data.payload.parts?.find(
                (p) => p.mimeType === "text/html"
            )?.body?.data;
    
            const htmlBody = body
                ? Buffer.from(body, "base64").toString("utf8")
                : "<p>(Sem conteúdo)</p>";
    
            res.send(`
          <h2>${id}</h2>
          <div>${htmlBody}</div>
          <a href="/">Voltar</a>
        `);
        } catch (err) {
            console.error(err);
            res.status(500).send("Erro ao carregar email");
        }
    });
    
    app.listen(PORT, () => console.log(`🚀 Servidor rodando em http://localhost:${PORT}`));
    
    Arquivo tokens.json

    Crie um arquivo JSON vazio, inicializando o objeto JSON conforme o código abaixo.

    {}
    public/index.html

    Crie o arquivo index.html dentro da pasta public. Altere o exemplo abaixo com o e-mail que você utilizará para testar a API. No meu caso, estou utilizando o meu e-mail pessoal para testar.

    <!DOCTYPE html>
    <html lang="pt-BR">
    
    <head>
        <meta charset="UTF-8" />
        <title></title>
        <style>
            body {
                font-family: Arial;
                margin: 20px;
            }
    
            input,
            button {
                padding: 8px;
                margin-top: 5px;
            }
    
            .email-item {
                border-bottom: 1px solid #ccc;
                padding: 5px;
            }
    
            .email-item:hover {
                background: #f5f5f5;
                cursor: pointer;
            }
        </style>
    </head>
    
    <body>
        <section id="auth">
            <button id="authButton">Autenticar</button>
            <button id="loadEmailsBtn">Carregar E-mails</button>
        </section>
    
        <h2>Emails</h2>
        <div id="emailsList"></div>
    
        <script>
            const authButton = document.getElementById('authButton');
            const loadEmailsBtn = document.getElementById('loadEmailsBtn');
            const emailsList = document.getElementById('emailsList');
    
            authButton.onclick = async () => {
                if (!email) return;
    
                // Nesse exemplo eu estou usando o meu e-mail, altere para o e-mail que você vai logar no oauth
                // qualquer dúvida é só entrar em contato
    
                try {
                    const response = await fetch(`http://localhost:4000/oauth/redir/leandro.edgedigital@gmail.com`, {
                        method: 'GET',
                        credentials: 'include',
                        headers: {
                            'Content-Type': 'application/json',
                        }
                    });
    
                    const data = await res.json();
                    window.location.href = data.url;
                } catch (error) {
                    console.error('Erro:', error);
                }
            };
    
            loadEmailsBtn.onclick = async () => {
                loadEmails("leandro.edgedigital@gmail.com");
            }
    
            async function loadEmails(email) {
                const res = await fetch(`/emails/${email}`);
                const emails = await res.json();
    
                emailsList.innerHTML = emails.map(e => `
            <div class="email-item" onclick="viewEmail('${email}','${e.id}')">
              <strong>${e.subject}</strong><br>
              <small>${e.from}</small>
            </div>
          `).join('');
            }
    
            async function viewEmail(email, id) {
                window.location.href = `/email/${email}/${id}`;
            }
        </script>
    </body>
    
    </html>

    Rodando o projeto

    Para rodar o projeto, execute o código abaixo dentro da pasta do projeto.

    node server.mjs

    Ao executar o código acima, você deverá ver a seguinte mensagem em seu terminal/prompt de comando:

    node server.mjs
    
    🚀 Servidor rodando em http://localhost:4000

    Abra o seu navegador na página http://localhost:4000 e teste clicando em Autenticar.

    Após a autenticação, visualize os e-mails de sua caixa de entrada clicando em Carregar E-mails e visualize o conteúdo do e-mail clicando no e-mail ou acessando http://localhost:4000/email/:seu-email-gmail/:id-do-email

    Espero que tenham gostado! Se tiver algum erro, é só entrar em contato comigo em meu e-mail leandro.edgedigital@gmail.com! Até!

  • Fazer a autenticação com as APIs do Google permite que sua aplicação web acesse serviços em nome dos seus usuários. Neste artigo, vou mostrar como configurar sua aplicação para se autenticar com as APIs do Google usando o OAuth.

    De forma geral, o que faremos é configurar um aplicativo OAuth dentro do Google Cloud Platform (GCP) e, em seguida, implementar o fluxo de autenticação OAuth na nossa aplicação para que tudo funcione corretamente.

    Se você ainda não está familiarizado com o conceito de OAuth, recomendo dar uma olhada neste guia introdutório antes de continuar.

    Visão geral do processo

    Antes de mergulharmos na implementação do OAuth 2.0 com o Google para acessar as APIs da plataforma, vale a pena entender de forma resumida como funciona o fluxo geral dessa autenticação.

    • (A) Redirecionar o usuário do navegador para o Google:
      O usuário clica em um botão em seu front-end e é redirecionado para o Google, onde pode conceder permissão para que o app acesse sua conta.
    • (B) Retornar o usuário do Google para o navegador:
      Depois que o acesso é concedido, o Google redireciona o usuário de volta ao navegador, enviando junto um código de autorização.
    • (C) Realizar a troca do código de autorização por um token:
      Esse código é enviado do navegador para o servidor da aplicação, que faz a troca com o Google. Nessa etapa, o Google retorna um access_token (token de acesso) e, em muitos casos, também um refresh_token (token de atualização).
    • (D) Usar o token de acesso para fazer requisições às APIs do Google:
      Com o access_token, a aplicação pode realizar chamadas às APIs do Google em nome do usuário. Caso o token expire, o refresh_token pode ser utilizado para obter um novo access_token sem que o usuário precise se autenticar novamente.

    Pronto! Agora já temos tudo o que precisamos para implementar o OAuth 2.0 com o Google Cloud Platform (GCP) e começar a acessar as APIs do Google.

    Agora vamos criar o seu aplicativo OAuth no Google Cloud Platform (GCP)

    1. Crie uma conta no Google Cloud Platform (GCP) acessando: https://cloud.google.com
    2. Depois de acessar o painel do GCP, vá até o menu Google Auth Platform e selecione Clientes.
    3. A partir daí, você poderá criar um novo ID do cliente OAuth, que será usado para gerenciar o processo de autenticação entre sua aplicação e as APIs do Google.

      Durante o preenchimento do formulário, selecione o Tipo de Aplicativo como Aplicativo da Web, escolha um nome para o seu ID do Cliente, adicione em Authorized redirect URIs (URIs de redirecionamento autorizadas) uma URL de redirecionamento, como por exemplo:
      http://localhost:4000/oauth/receive

      Após preencher o formulário, clique em criar.
    4. Depois clique em Branding e preencha com o nome do app que você deseja que apareça em seu teste.

    Pronto, é isso! Anote o ID do Cliente (Client ID) e a Chave secreta do cliente (Client Secret) do seu novo Cliente OAuth e mantenha essas informações para que você consiga interagir futuramente com o seu cliente recém criado.