Validação de Requisições no Laravel
Adicione essa camada extra de segurança à sua aplicação.
Contextualizando
Vamos dar uma relembrada no conceito clássico de Cliente-Servidor. Na computação, especificamente em redes, em uma conexão existem dois elementos um cliente e um servidor.
O cliente pode ser seu browser, ou aplicação instalada no seu celular, o servidor é onde seu cliente obtêm informações, por exemplo, ao acessar o site do Medium (servidor) pelo Chrome (client) você faz uma série de requisições pedindo/enviando dados para os servidores do Medium e o que você tem em troca é a página inicial do Medium ou de onde você deseja ir.
Tudo isso ocorre por baixo dos panos, mas podemos dar uma olhada através da aba Network do ‘devtools’ do seu browser, como você pode ver no screenshot abaixo:
Métodos HTTP
Como explicado você pode enviar/pedir dados para o servidor, quando enviamos uma requisição ‘pedindo’ algo usamos o método GET, quando fazemos uma requisição enviando algo para o servidoer (como um formulário por exemplo) fazemos uma do tipo POST. Essas são as padrões, mas também temos o método PUT para editar informações, DELETE para remover informações e algumas outras.
Isso é o básico do básico sobre requisições, não vou me aprofundar pois não é o intuito do artigo. Se você não sabe o que são as requests, eu recomendo que leia HTTP Request Methods — W3Schools e Métodos de Requisições — Mozilla Developer.
A validação de Requests
Até aí ok, mas e se essas requests forem maliciosas? Digo, se um usuário mal intencionado fazer uma request em uma página administrativa, o que impedirá ele de acessar informações sigilosas ou até mesmo corromper a integridade do sistema? Ou então se um usuário desatento enviar dados inválidos em um formulário, esses dados serão inseridos no banco de dados de qualquer jeito?
Cuidar e validar as requisições é um dos primeiros passos para adicionar um mínimo de segurança e estabilidade para uma aplicação. O Laravel por padrão já oferece algumas proteções na camada de Requests como, por exemplo, Proteção à CSRF.
Nesse artigo eu vou me focar em validação de dados enviados por formulário e recomendo que você não se limite somente ao que está escrito aqui, e sim vá além, na documentação oficial você encontrará bastante conteúdo a respeito dos diferentes tipos de validações.
Configurando o Ambiente
Para exemplificar como são feitas validações de requests, vou criar um ambiente de exemplo onde o usuário através de um formulário irá digitar seus dados e a nossa aplicação terá a responsabilidade de checar esses dados digitados, caso estes dados sejam inválidos iremos redirecioná-lo novamente ao formulário com mensagens de erro, e se forem válidos vamos dar um dump nesses dados.
Controller
Sem entrar em muito detalhes você precisa de um UserController e nele vamos ter um método chamado ‘store’.
O método store em uma aplicação é responsável por inserir os dados no DB, como não iremos trabalhar com base de dados aqui, vamos apenas ‘jogar na tela’ a requisição que será feita pelo usuário no momento em que ele enviar o formulário, o método ficará assim:
public function store(Request $request)
{
// Jogue na tela a Request do Usuário
dd($request);
}
Se não sabe como funcionam os Controllers no Laravel, dê uma lida nessa parte da documentação.
Rotas
Vamos criar uma rota e editar uma já existente.
A rota ‘/’ retornará a view ‘form’ que criaremos daqui a pouco, também vamos criar uma rota que irá receber os dados do formulário e enviar para o método store criado no controller.
No fim das contas, arquivo de rotas deverá ter as seguintes configurações:
// Rota '/' irá retornar um formulário
Route::get('/', function () { return view('form');});
// Os dados do formulário serão enviados para o método store de user
Route::post('/store', 'UserController@store')->name('user.store');
Se você não sabe o que estou fazendo aqui, dê uma lida a respeito das rotas no Laravel.
View
O formulário deverá ter os campos de input ‘name’, ‘email’, ‘password’ e ‘confirm_password’, todos esses com a propriedade ‘name’ setada. E não se esqueça de usar o token ‘@csrf’ e setar a propriedade ‘action’ do form para a rota criada.
Validando as Requisições
Tudo configurado, vamos para a validação.
Você pode perceber que o método store recebe um objeto do tipo Request, isso significa que a variável $request irá representar a requisição feita ao método, e no caso ela não trará somente os dados do formulário, mas outras informações como a sessão, método HTTP usado, e também terá métodos, entre eles o validate que é o que usaremos.
Antes de tudo, vamos setar no UserController as regras que nossos campos deverão ter:
$rules = [
// 'name' é obrigatório & deve ter o mínimo de 3 letras
'name' => 'required|min:3' // 'email' é obrigatório & deve ser válido
'email' => 'required|email' // é obrigatório, deve bater com a confirmação e ter 8 letras
'password' => 'required|min:8|confirmed'];
Caso queira ver mais regras de validação leia as Validation Rules especificadas na Documentação.
Agora vamos aplicar essa regra à requisição,
// Valide a request baseada nas regras descritas
$request->validate( $rules )
Agora, se a requisição não atender aos requisitos especificados, a execução do método será brecada e o usuário será redirecionado de volta para o formulário, mas se atender, o método continuará em execução.
No fim o método store ficará na seguinte maneira:
public function store(Request $request)
{ // Definição das regras
$rules = [
'name' => 'required|min:3',
'email' => 'required|email',
'password' => 'required|min:8|confirmed',
]; // Validação da Request
$request->validate($rules);
// Se tudo estiver certo, 'printe' na tela
dd($request);
}
Mostrando os erros para o usuário
Como o usuário será redirecionado de volta ao formulário, é possível mostrar as mensagens de erro. Para isso vamos usar a estrutura condicional if, que vai verificar se existem erros, se sim, ele irá percorrer os erros (com um foreach) e exibir cada um para o usuário, tudo isso será feito pelo blade. O arquivo form.blade.php ficará mais ou menos assim:
// Se existirem erros
@if($errors->all()) // Percorra os erros
@foreach($errors->all() as $error) // E crie uma div
<div class="alert alert-danger"> // Com a mensagem de erro
{{ $error }} </div> @endforeach@endif
Se você nunca viu essa estrutura no Blade, vou deixar o link que fala a respeito das estruturas condicionais e das estruturas de repetição.
Esse é só um exemplo de como você pode devolver as mensagens de erro para o usuário, na própria documentação do Laravel o processo é feito de maneira diferente, como você pode ver aqui.
Pronto, já estamos devolvendo a mensagem de erro para o usuário, porém, ainda podemos melhorar isso, quando um usuário erra apenas um campo do formulário, não é necessário que ele redigite todos os outros que estavam corretos, podemos ajustar isso editando as propriedades de ‘value’ nos inputs
<input type="text" id="name" name="name" value="{{ old('name') }}">
Basta setar a propriedade em todos inputs (exceto o de confirmação de senha) e os campos que estiverem corretos não precisarão ser redigitados.
Mensagens em inglês?
Caso você esteja desenvolvendo uma aplicação em português eu recomendo que dê uma olhada nesse pacote de tradução, mas caso queira ver como que você seta suas mensagens de erro personalizadas eu mostro como.
Do mesmo modo que as regras, as mensagens serão armazenadas em um array associativo que será consumido posteriormente. A sintaxe será:
'campo.erro' => 'mensagem',
'campo2.erro2' => 'mensagem22'
Então o array ficará mais ou menos assim:
$messages = [ 'name.required' => 'Opa! Parece que você se esqueceu de digitar seu nome.',
'name.min' => 'Calma aí, seu nome só tem duas letras? Tente novamente com seu nome real e seu sobrenome', 'email.required' => 'Hmm... Parece que você esqueceu de digitar seu e-mail.', 'email.email' => 'Hmm... Não sei seu e-mail, mas com certeza não é esse, tente novamente.', 'password.required' => 'Calma lá, precisamos saber sua senha para continuarmos.', 'password.confirmed' => 'Erros acontecem, suas senhas não batem, por favor tente novamente.'];
Para usar as mensagens personalizadas é só especificar no validate:
$request->validate($rules, $messages);
Conclusão
E aí? O que achou? A validação de requisições, mesmo que básica como nesse exemplo, demonstra que a aplicação em questão é bem desenvolvida e que o programador se preocupou com os ‘detalhes’.
Eu espero que tenha conseguido transmitir com clareza o que eu quis passar, e é claro, não deixe de ler a Documentação oficial do Laravel, especialmente a parte que fala a respeito de Validação de Requisições. Bons estudos!