https://a.storyblok.com/f/270183/182328/a230ebe23d/social_react-native_verify_1200x600.png

Adicionar verificação por SMS em um aplicativo React Native usando Node.js e Express

Publicado em November 5, 2020

Tempo de leitura: 5 minutos

O desenvolvimento de um aplicativo móvel traz muitos desafios. O React Native pode amenizar muitos desses desafios no que diz respeito ao suporte à compatibilidade entre plataformas, mas, obviamente, ainda há um esforço significativo de engenharia envolvido em qualquer aplicativo. Talvez você queira implementar a autenticação de dois fatores (2FA) por SMS para bloquear mais de 100% das invasões de contas por bots, ou até mesmo integrar uma ferramenta de marketing do tipo “compartilhe este aplicativo com seus amigos”.

Felizmente, a Vonage torna a integração de recursos como esses ao seu aplicativo uma brincadeira de criança!

O que vamos criar?

Nosso objetivo hoje é criar um aplicativo que permita aos usuários “criar um Account” usando seu número de telefone e a autenticação de duas etapas (2FA) por SMS. Além disso, assim que o usuário estiver “conectado”, permitiremos que ele selecione um contato de sua lista de contatos e envie um convite para usar o aplicativo para o celular dessa pessoa por SMS.

Para habilitar essa funcionalidade, vamos usar o React Native para a interface do usuário e um servidor Node/Express no back-end.

Para manter o foco deste artigo, vamos começar com uma interface de usuário já pronta. Este aplicativo React Native não está conectado a nenhum servidor, mas sua interface de usuário já está configurada com dados simulados. O aplicativo, nesse estado, é relativamente pequeno (~300 LOC) e é totalmente de código aberto.

A demo of the React Native app with mocked data and no server connectivityA demo of the React Native app with mocked data and no server connectivity

Configurar o Account da Vonage

Agora que já temos uma interface de usuário pronta, podemos começar a trabalhar no servidor. Para habilitar as funcionalidades que queremos, vamos usar hoje duas das APIs da Vonage:

{"type":"signUp","props":{"number":false}}

Depois de criar um Account, você poderá encontrar sua chave de API e seu segredo de API na parte superior do Painel da API da Vonage.

The Vonage dashboard showing the API secretsThe Vonage dashboard showing the API secrets

Assim que tivermos esses valores, vamos armazená-los em um .env arquivo:

NEXMO_API_KEY=XXXXXXXX NEXMO_API_SECRET=XXXXXXXXXXXXXXXX

Não se esqueça de adicionar o .env arquivo às suas .gitignore regras! Você não vai querer acabar numa situação em que git commit seus segredos de API!

Precisaremos de mais um dado do painel para nossa análise: o número de telefone associado à sua conta da Vonage. Você pode encontrá-lo em Numbers > Seus números.

The numbers tab in the Vonage dashboard with the number area highlightedThe numbers tab in the Vonage dashboard with the number area highlighted

Mais uma vez, vamos armazenar esse valor no mesmo .env arquivo para uso posterior:

NEXMO_NUMBER=5555555555

Certifique-se de excluir quaisquer outros símbolos além dos próprios números. O SDK da Vonage prefere que se utilize um número de telefone sem formatação no código.

Configurar o Express Server

É difícil configurar a funcionalidade de um aplicativo que exija um back-end sem um servidor em funcionamento! Por isso, vamos começar com um modelo de código do Express. Vá em frente e crie um app.js arquivo e comece com o seguinte modelo:

// app.js
const express = require('express')
const bodyParser = require('body-parser')
const app = express()
const port = process.env.PORT || 3000

app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json())

app.get('/', (req, res) => {
    res.send({message: "Hello, world!"});
});

app.listen(port, () => console.log(`Example app listening at http://localhost:${port}`))

Esse código deve nos permitir usar JSON como corpo das nossas solicitações e acessá-los posteriormente por meio de req.body. Se enviássemos um solicitação POST para /test com a carga útil {hello: "Hi there"}, poderíamos acessar "Hi there" por meio de req.body.hello.

Assim que tivermos nosso código inicial do Express em execução, precisaremos configurar o SDK do Vonage Node. Esse pacote oferece todas as funcionalidades de que precisaremos para integrar as APIs do Vonage ao nosso aplicativo.

Vamos começar adicionando o pacote ao nosso projeto:

npm i nexmo

Depois de fazer essa configuração, podemos executar o construtor no início do nosso arquivo para podermos usar as APIs posteriormente:

const Nexmo = require('nexmo');

const nexmo = new Nexmo({
    apiKey: process.env.NEXMO_API_KEY,
    apiSecret: process.env.NEXMO_API_SECRET,
});

Solicitar um código de verificação

Vamos começar criando o código para solicitar e verificar um código SMS de autenticação de duas etapas (2FA). Começaremos pela parte do código relacionada à solicitação:

app.post('/request', (req, res) => {
    // We verify that the client has included the `number` property in their JSON body
    if (!req.body.number) {
        res.status(400).send({message: "You must supply a `number` prop to send the request to"})
        return;
    }
    // Send the request to Vonage's servers
    nexmo.verify.request({
        number: req.body.number,
        // You can customize this to show the name of your company
        brand: 'Vonage Demo App',
        // We could put `'6'` instead of `'4'` if we wanted a longer verification code
        code_length: '4'
    }, (err, result) => {
        if (err) {
            // If there was an error, return it to the client
            res.status(500).send(err.error_text);
            return;
        }
        // Otherwise, send back the request id. This data is integral to the next step
        const requestId = result.request_id;
        res.send({requestId});
    });
})

Conforme indicam os comentários do código, quando enviamos uma solicitação de código para um número, recebemos um request_id. Precisamos devolver esse código ao cliente e armazená-lo no estado. Isso nos permitirá enviar a solicitação de “verificação” assim que o usuário receber o próprio código de solicitação.

Dito isso, assim que o usuário fizer a solicitação, ele precisa ter uma maneira de verificar isso, não é mesmo? Vamos configurar essa rota agora:

app.post('/verify', (req, res) => {
    // We require clients to submit a request id (for identification) and a code (to check)
    if (!req.body.requestId || !req.body.code) {
        res.status(400).send({message: "You must supply a `code` and `request_id` prop to send the request to"})
        return;
    }
    // Run the check against Vonage's servers
    nexmo.verify.check({
        request_id: req.body.requestId,
        code: req.body.code
    }, (err, result) => {
        if (err) {
            res.status(500).send(err.error_text);
            return;
        }
        res.send(result);
    });
})

Em uma aplicação mais pronta para produção, provavelmente integraríamos isso a um sistema de autenticação, como Passport. Devido à simplicidade das APIs envolvidas, a integração deve ser relativamente simples.

Agora que temos uma “confirmação” de que o número de telefone do usuário foi verificado, podemos seguir em frente com a interface do usuário.

Chamar o servidor a partir do React Native

Como já configuramos a maior parte da lógica na interface do usuário, nossa configuração no React Native é bem simples. Usaremos a fetch API para fazer chamadas ao servidor:

// services.js
// Using the npm package `ngrok`, we can temporarily "deploy" our local server to test against 
const SERVER_BASE = 'http://test.ngrok.io'

export const request = ({ phoneNumber }) => {
  return fetch(`${SERVER_BASE}/request`, {
    method: 'post',
    // Tell our server we're sending JSON
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      number: phoneNumber,
    }),
  })
}

export const verify = ({ requestId, code }) => {
  return fetch(`${SERVER_BASE}/verify`, {
    method: 'post',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      requestId,
      code,
    }),
  })
}

Basta chamar esses métodos dentro do código do React, como faria com qualquer outra API, e pronto!

SMS DemoSMS Demo

Enviar um SMS

Se você assistir à demonstração até o fim, vai perceber que conseguimos escolher um contato da nossa lista de contatos e enviar a ele um SMS de convite para usar o aplicativo!

Felizmente, isso é tão simples de implementar quanto o verify código. Voltando ao Express, adicionar outra rota para enviar mensagens de texto é fácil:

// app.js
// We need the phone number now to send an SMS
const nexmoNumber = process.env.NEXMO_NUMBER;

app.post('/invite', (req, res) => {
    if (!req.body.number) {
        res.status(400).send({message: "You must supply a `number` prop to send the request to"})
        return;
    }
    // Customize this text to your liking!
    const text = 'You\'re invited to use the hot new app! Details here:';
    const from = nexmoNumber;
    // This regex removes any non-decimal characters. 
    // This allows users to pass numbers like "(555) 555-5555" instead of "5555555555"
    const to = req.body.number.replace(/[^\d]/g, '');

    nexmo.message.sendSms(
        from,
        to,
        text,
        {},
        (err, data) => {
            if (err) {
                const message = err.message || err;
                res.status(500).send({message});
                return;
            }
            res.send(data);
        }
    );
})

Em seguida, adicionar o último trecho de código ao arquivo do React Native services.js é igualmente fácil:

export const invite = ({ phoneNumber }) => {
  return fetch(`${SERVER_BASE}/invite`, {
    method: 'post',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      number: phoneNumber,
    }),
  })
}

Conclusão

Se você quiser ver o exemplo de código completo (tanto do servidor Express quanto do aplicativo React Native), você pode encontrar esse código hospedado no GitHub.

Embora o aplicativo tenha começado bem, talvez possamos transformar o envio de SMS aos usuários um sistema interativo de envio de SMS. Se você tiver alguma ideia de como adicionar funcionalidades ao aplicativo, sinta-se à vontade para participar da conversa em nossa Slack da Comunidade de Desenvolvedores da Vonage.

Por fim, não deixe de acompanhar a conta do a conta do Vonage Developer no Twitter!

Compartilhar:

https://a.storyblok.com/f/270183/384x384/25ea95a56d/corbin-crutchley.png
Corbin Crutchley

Corbin in a passionate developer, teacher, and retro game enthusiast. Driven to help others, they started a site called Unicorn Utterances to help engage the community and provide a place for learning CS topics.