ToDoVel [Parte 21] Filtros das Rotas

Observação: Este tutorial refere-se ao Laravel-4-BETA, estando totalmente DESATUALIZADO para a versão atual. Muita coisa mudou no framework…

Laravel possui um esquema muito bacana de filtros de rota.
Você pode utilizar filtros nas rotas para executar ações antes ou depois de executar a closure da rota.
Os filtros devem ser escritos no arquivo app/filters.php, e Laravel já vem com alguns filtros bem legais.
Saiba mais sobre Route Filters.

Nesse post vamos aprender a utilizar os filtros a partir de dois exemplos muito úteis.

CSRF

Cross-site Request Forgery é uma tática onde sites terceiros tentam fazer uso da navegação do usuário para fuder sacanear seu site.
A forma mais simples de evitar que isso aconteça com você é passar um token entre as páginas que executam ações no seu site, como formulários.
O Laravel possui essa facilidade, tanto para passar o Token pela sessão, como o filtro para verificar se o Token existe.

Primeiro precisamos passar o Token.
Para isso, vou lá no formulário do login.blade.php e crio um campo hidden, assim (no exemplo, coloquei o campo antes do botão de submit):

<input type="hidden" name="_token" value="{{ csrf_token() }}" />
<input type="submit" value="Login">

O filtro para verificar se o token CRSF existe na requisição já vem pronto no Laravel, e está dentro do arquivo app/filters.php.
Só precisamos utilizá-lo na rota de POST do login.
routes.php

Route::post('login', array('before' => 'csrf', function() {

Calma!
Vamos lá.

O que aconteceu foi o seguinte: a rota anterior para o POST recebia o endereço da rota (‘login’) e a closure para ser executada.
Agora a rota está recebendo o endereço (DUH!) e um array, bem parecido como quando definimos as rotas nomeadas, lembra?
Nesse array é passado a chave “before” que diz ao Laravel qual o filtro que deve ser executado ANTES de executar a closure da rota.
E claro, é passada a closure para ser executado.

Apenas Usuários Autenticados

Agora que nós temos um super hiper mega ultra power sistema de login seria legal que apenas usuários logados pudessem acessar as páginas da nossa aplicação.
Para isso, vamos utilizar os filtros.
YAAAAAYYYY!!!!
Nesse caso, o filtro também já existe.
Podemos utilizar o filtro auth.basic, que faz com que um pop-up apareça na tela do usuário, ou utilizar o filtro auth, que tenta redirecionar para a tela de login que criamos.
Vamos dar uma conferida lá no filtro de auth

Route::filter('auth', function()
{
	if (Auth::guest()) return Redirect::route('login');
});

É uma simples função Laravel que verifica se o usuário está logado.
Se não estiver, redireciona para a rota de nome login.
Porém, nossa rota não tem nome.
Temos então duas opções: dar nome aos bois a rota ou alterar o redirecionamento para Redirect::to(‘login’).
Eu prefiro dar nome a rota 🙂

Grupo de Rotas

Agora a gente vai ter que alterar todas as rotas que fizemos nesse projeto para colocar o filtro de auth.
Ai é foda…
Mas espere!
Isso aqui é Laravel.
E Laravel tá ai para facilitar as atividades do dia-a-dia.
Para que escrever um filtro em cada rota se podemos agrupar todas as rotas em um filtro? (frase mal escrita e sem sentido)

Documentação sobre o Route Groups.

Vamos criar um grupo para executar o filtro de Auth.

Route::group(array('before' => 'auth'), function()
{
    //colocar aqui dentro as rotas que devem ter o filtro auth
});

E ai, é só copiar e colar as rotas para dentro do grupo.
Assim, nosso arquivo routes.php vai ficar assim:

<?php

Route::group(array('before' => 'auth'), function()
{
	//home
	Route::any('/', array("as" => "home",
			      function() { return View::make('hello'); }
			      )
	);
	
	Route::get('ola/{usuario?}', 'HomeController@ola');
	
	/*    listing tasks    */
	Route::any('task', 'TaskController@listar');
	Route::any('tasks', 'TaskController@listar');
	
	/*    adding tasks routes    */
	Route::get('task/add/{lista_id}', 'TaskController@getAdd');
	Route::post('task/add/{lista_id}', 'TaskController@postAdd');
	
	/*    checking tasks    */
	Route::post('task/check', 'TaskController@check');
	
	/*    lists    */
	Route::get('list/create', 'ListController@getCreate');
	Route::post('list/create', 'ListController@postCreate');
	
	Route::get('list', 'ListController@listar');
	Route::get('list/{lista_id?}', 'ListController@listarTasks');
});




/*    login    */
Route::get('login', ['as'=>'login', function() {
	return View::make('login');
}]);

Route::post('login', array('before' => 'csrf', function() {
	$regras = array("email" => "required|email",
			"senha" => "required");
	
	$validacao = Validator::make(Input::all(), $regras);
	
	if ($validacao->fails()) {
		return Redirect::to('login')->withErrors($validacao);
	}
	
	//tenta logar o usuário
	if (Auth::attempt( array('email' => Input::get('email'), 'password' => Input::get('senha') ) ) ) {
		return Redirect::to('/');
	}
	else {
		return Redirect::to('login')->withErrors('Usuário ou Senha Inválido');
	}
}));

Pra ver como está ficando o código, acesse o GittHub:
https://github.com/frenetic/todovel

7 thoughts on “ToDoVel [Parte 21] Filtros das Rotas

  1. Por acaso vc saberia me dizer se eu não posso fazer assim:
    Route::get(‘login’, [‘as’=>’login’, ‘LoginController@getLogin’]);
    e o post assim:
    Route::post(‘login’, array(‘before’ => ‘csrf’, ‘LoginController@postLogin’));

    ou como eu teria que fazer se ao invés de eu fazer essa closure?

    mais uma vez, muito obrigado

  2. Ola brother, tudo bem?
    Gostaria primeiramente de te parabenizar pelo seu tutorial!
    Segundo gostaria de te fazer uma pergunta 🙂 como poderia fazer o logout do usuario?

    Abraçao.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *