Um recurso de segurança em autenticação de sistemas que vem se popularizando bastante nos últimos tempos é a verificação em 2 etapas. Os principais aplicativos de bancos e corretoras utilizam seus próprios apps para gerar tokens que são dinâmicos (eles são atualizados constantemente em baixos ciclos de tempo), e utilizados como 2º fator para acesso ao sistema (o 1º fator é o tradicional usuário/email e senha).
Todavia, caso você não queira implementar o seu próprio gerador de tokens, você pode utilizar o Google Authenticator, um aplicativo com as características citadas (disponível para Android e IOS) e que pode facilmente ser integrado ao seu aplicativo ou sistema web. Nesse post, eu vou mostrar para vocês como integrar sua aplicação php com o Google Authenticator.
Basicamente, o usuário do app/sistema precisa associar a conta dele ao aplicativo do Google Authenticator instalado em seu smartphone. Essa associação é feita através da leitura de um QR Code, ou informando o código manualmente (em ambos os casos, o código deve ser gerado a partir do próprio sistema). Na imagem à seguir, é possível visualizar a interface principal do app Google Authenticator. Cada conjunto de 6 dígitos referem-se a um sistema específico.

Para integrar uma aplicação php com o Google Authenticator, vamos utilizar a biblioteca sonata-project/GoogleAuthenticator (https://github.com/sonata-project/GoogleAuthenticator). Vamos fazer a instalação dela através do composer.
composer require sonata-project/google-authenticator |
No nosso exemplo, vamos ter 2 arquivos:
- genqrcode.php – responsável por gerar o código QR Code, para que o usuário/utilizador faça o scan
- check.php – valida o código de 6 dígitos (gerados pelo Google Authenticator) e então libera ou não o acesso ao sistema
No arquivo genqrcode.php vamos inserir o seguinte código:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <?php include_once 'vendor/sonata-project/google-authenticator/src/FixedBitNotation.php'; include_once 'vendor/sonata-project/google-authenticator/src/GoogleAuthenticatorInterface.php'; include_once 'vendor/sonata-project/google-authenticator/src/GoogleAuthenticator.php'; include_once 'vendor/sonata-project/google-authenticator/src/GoogleQrUrl.php'; $g = new \Google\Authenticator\GoogleAuthenticator(); $secret = 'XVQ2UIGO75XRUKJO'; //Você pode usar o $g->generateSecret() para gerar o secret //$secret = $g->generateSecret(); //o método "getUrl" recebe como parâmetro: "username", "host" e a chave "secret" echo '<img src="'.$g->getURL('rafaelwendel', 'rafaelwendel.com', $secret).'" />'; ?> |
Na linha 8 eu criei uma varíavel chamada “$secret”. Essa variável será responsável por armazenar a chave da minha aplicação. Recomendo que você utilize uma boa chave. Quanto melhor, mais seguro. Essa chave deve ser usada no momento de gerar o QR Code, e posteriormente devemos usar a mesma chave para poder validar um código de autenticação.
Na linha 10 é gerado uma imagem (QR Code) para que o usuário/utilizador faça o scan a partir do app Google Authenticator em seu celular.
Por fim, vamos implementar o arquivo check.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <?php include_once 'vendor/sonata-project/google-authenticator/src/FixedBitNotation.php'; include_once 'vendor/sonata-project/google-authenticator/src/GoogleAuthenticatorInterface.php'; include_once 'vendor/sonata-project/google-authenticator/src/GoogleAuthenticator.php'; include_once 'vendor/sonata-project/google-authenticator/src/GoogleQrUrl.php'; $g = new \Google\Authenticator\GoogleAuthenticator(); $secret = 'XVQ2UIGO75XRUKJO'; $code = '010989'; //código de 6 dígitos gerados pelo app do Google Authenticator if($g->checkCode($secret, $code)){ echo 'Autorizado!'; } else{ echo 'Código incorreto ou expirado!'; } |
Na linha 11 eu insiro o código gerado pelo app do Google Authenticator. Obviamente, você terá um formulário para que esse código seja preenchido pelo usuário, submetido e recuperado. Lembre-se que esse código é dinâmico e o ciclo de vida dele é extremamente curto (apenas alguns segundos). Perceba também que na linha 9 eu utilizo a chave “$secret”, e ela deve ser EXATAMENTE a mesma que definimos lá no genqrcode.php
Para efetuar a verificação e então liberar o acesso, o código gerado pelo app e a chave “$secret” serão analisados no método “checkCode”.
Espero que gostem do conteúdo e qualquer dúvida deixe seu comentário.
Abs!
Fiz o download da lib https://github.com/sonata-project/GoogleAuthenticator
Obtive o secret no https://console.developers.google.com/
Esta gerando o qr code e funcionou scaneando no google authenticator
Mas ao digitar o 6 digitos do vodigo dentro do tempo, mesmo digitando certo ocorre o erro: Código incorreto ou expirado!
Ao tentar usar o codigo exemplo nao funciona https://github.com/sonata-project/GoogleAuthenticator/blob/2.x/sample/example.php
Olá Marcelo,
O host que você está colocando no “$g->getUrl” é o mesmo que você está usando para hospedar seu código? Tente também utilizar o mesmo “$secret” que eu usei nos exemplos, ao invés de gerar um pelo Google Developers.
Lembrando que depois de alterar essas informações no seu código, você deverá excluir e adicionar de novo o serviço no app Authenticator do seu celular.
Abs!
Rafael, bom dia!
Eu percebi que se várias pessoas lerem o QRCode gerado na tela, elas vão sempre gerar o código igual e com isso, passar pela verificação da segunda etapa, independe da fase usuário e senha (primeira etapa).
Seria isso mesmo?
Olá Álvaro.
Perceba que nas linhas 12 e 13 do arquivo genqrcode.php eu insiro o código para gerar o qrcode.
Perceba que o primeiro parâmetro do método getUrl é justamente o nome de usuário (username) da pessoa que está habilitando os 2 fatores.
Obviamente, no sistema não terá usuários com o “username” duplicados, logo sempre será passado um “username” diferente e portanto sempre será gerado um qrcode diferente.
Abs!
Verdade, que vacilo. kkkk
Muito obrigado.