Utilizando JWT no Lumen — parte 2 (Incluindo mais um método de autenticação)

Utilizando JWT no Lumen — parte 2 (Incluindo mais um método de autenticação)

Fala pessoal!
Vou continuar uma segunda parte sobre o tema, pois iria ficar muito grande fazer tudo em uma parte só o que acabaria sendo extremamente cansativo, eu particularmente odeio ler artigos gigantes de códigos.
Caso você tenha caído aqui sem saber do que se trata, veja a primeira parte aqui

Utilizando JWT no Lumen — parte 1

Em que consiste a parte 2 deste artigo?

Nessa segunda parte iremos deixar a nossa API um pouco mais comercial, deixando obviamente o login via email/senha , porém criando 2 chaves que são padrão para qualquer API, que é o clientId e o clientSecret e com isso faremos umas pequenas modificações no código para conseguir logar tanto com o email/senha quanto com as credenciais de client.
Além disso quando o cliente se registar, iremos enviar um e-mail para ele de boas vindas com as credenciais dele prontas para o uso utilizando uma Trait de Observer!

O que vamos precisar para iniciar

Para ficar legal e ver certinho o esquema do curso é necessário que você faça um cadastro de graça no mailtrap.io

Mailtrap – Email Testing Tool #1

O mailtrap.io é um servidor de teste para e-mail simples, você vai enviar e receber lá como se fosse um usuário final, mas sem ir pra ninguém somente para teste. Eu uso bastante para fazer teste de envio de e-mail para não atolar nenhuma caixa de email.

feito o cadastro ele vai te indicar pra colocar algumas variáveis no seu .env

Feito isso precisamos agora instalar o pacote do mail no Lumen, pois como sempre digo, ele vem só o básico para ser mais rápido e só incluímos o que realmente precisamos
Vamos executar o comando do composer

composer require illuminate/mail

e esperar terminar.

Depois de terminado iremos precisar ativar o mail dentro do nosso Lumen entrando lá no boostrap/app.php e colocando os seguintes registros

$app->configure(‘mail’);
$app->register(\Illuminate\Mail\MailServiceProvider::class);
$app->alias(‘mailer’, Illuminate\Mail\Mailer::class);
$app->alias(‘mailer’, Illuminate\Contracts\Mail\Mailer::class);
$app->alias(‘mailer’, Illuminate\Contracts\Mail\MailQueue::class);

Eu deixei em negrito esse configure pois iremos precisar criar esse arquivo de configuração pegando exatamente o mesmo do Laravel (que está aqui abaixo)
Você vai criar esse arquivo na mesma pasta config que esta o auth.php com o nome de mail.php

Feito todo esse processo é necessário reiniciar o seu Lumen e acionando novamente como php -S 0.0.0.0:8000 -t public

Modificando nosso banco para suportar o client id e secret

Agora com o email funcionando vamos alterar nossa tabela para incluir os 2 outros campos (client_id e client_secret) no nosso sistema.
Para isso vamos executar um comando do artisan para criar um migration de uma tabela já criada somente para adicionarmos os campos faltantes

php artisan make:migration --table=users insert_client_id_client_secret

Esse comando cria um arquivo limpo, porém relacionado à uma tabela em questão, a ‘users’
É só adicionar esses campos no up(){…}.
Eu coloco sempre o after porque eu gosto que o created_at e updated_at sempre fiquem como últimos campos, mas é somente estética.

Schema::table('users', function (Blueprint $table) {
$table->string('client_secret')->after('password');
$table->string('client_id')->after('password');
});

Aí é só executar o comando php artisan migrate que será incluído estes 2 campos na sua tabela!

Alterando o model, Mutator e Observer

Vamos começar com o registro de um usuário novo que automaticamente gerará o client id e secret, além de enviar um e-mail de boas vindas ao usuário da nossa API.
Primeira coisa, Mutators eu dei uma explicada por cima no artigo anterior, mas basicamente consiste no seu modelo você sobrepor a chamada do set/get por meio de métodos. No nosso caso iremos criar automaticamente o client_id e client_secret, porém ao gerar iremos concatenar client_id_xxxx e client_secret_xxxx e para isso iremos usar o Mutator assim setClientIdAttribute($val) onde sempre é fixo o set e o Attribute e o que muda é só o nome da propriedade sempre em CamelCase.

Agora vamos criar a Trait Observer que ficará ‘escutando’ nosso modelo e irá executar alguma ação sempre após outra, ou seja, quando o cliente for inserido no banco nós iremos executar alguma ação

Para isso dentro da nossa pasta Traits que criamos anteriormente vamos criar uma pasta chamava Observers para separar o código e dentro dela vamos criar um arquivo chamado UserObserver.php que está abaixo.
Mas qual motivo vamos usar uma trait?
A Trait do php nada mais é do que um bloco de código que inicialmente não vem vinculo com nenhuma classe e pode ser praticamente acoplada com qualquer uma, portanto fica mais fácil trabalhar com traits nesse caso.

Seu model User.php deverá ter ficado igual ao arquivo abaixo, sem esquecer de criar no fillable o client_id e o client_secret e também fazendo a inclusão da trait no use da classe

Alterando o nosso AuthController

Agora precisamos alterar nosso AuthController para alterar o método de registro do usuário, inserindo o client_id e secret por meio do mutator e também alteração do método de login, para contemplar tanto clientes com e sem o client_id

A primeira coisa que vamos fazer é criar um método para gerar uuids randômica e única para cada um dos 2 campos , assim nosso sistema fica a prova de duplicidade, porém você pode incluir um método antes de incluir para ter certeza que realmente não está duplicado, mas com o random_bytes isso não acontece (é o método que vamos utilizar)

Vamos criar um método chamado generateApiKey() e nela vamos criar o uuid único que será retornado como resultado do próprio método

Esse método basicamente cria um uuid único para quem requisitou.

Então iremos modificar nosso método de register para contemplar essa chamada e inclusão do nosso client_id e client_secret bem simples

Alterando o login

Agora com tudo funcionando, registro, e-mail e etc, Vamos para a parte final desse segundo artigo.

Iremos alterar o método de login, mas sem quebrar o outro. Mas como iremos fazer isso? Simples, vamos incluir mais um campo no post chamado grant_type e nele iremos dizer se queremos o login via credential ou não. caso o grant_type for inserido com “credential” ele vai validar e logar com o credencial de client id/secret, caso não estiver nada ou qualquer coisa diferente de credential ele vai tentar logar via email/senha
Para isso vamos alterar o nosso método isLoginValid para isLoginEmailValid e criar um outro chamado isLoginCredentialValid onde vamos validar os dados de entrada para ver se está tudo certo para não dar nenhuma exceção desnecessária
Vou colar o trecho do código mas está tudo no GitHub logo no começo do artigo.

O mais importante, mantemos o método login, portanto, não iremos quebrar o método de login da V1 para a V2, e o que fazemos basicamente é procurar o campo grant_type para saber qual login fazer, se é via credencial ou via email/senha.

Feito isso você já está apto a usar o endpoint /me para pegar as informações do seu usuário.
E finalizamos a alteração do endpoints para receber dois tipos de autenticação

Lembre-se que você pode baixar as collections do POSTMAN nesse link abaixo que será sempre atualizado

Para ir para a terceira parte do artigo só clicar abaixo

E também o link do repositório da V2

brasizza/lumen-jwt-v2