Em algumas situações precisamos, de alguma forma, catalogar as seções que são acessadas em uma aplicação Web para fins de auditoria ou até mesmo log de segurança. Uma técnica que é comumente utilizada é ter uma página ou ação que receba toda a demanda para qualquer link que se clique, e a partir de parâmetros que são colocadas em querystrings, este centralizador será capaz de realizar o log, e em seguida, redirecionar o usuário para a página solicitada.
Podemos eleger uma ação que será a centralizadora e todos os links serão renderizados apontando para ela incluindo o parâmetro o caminho da ação real a ser executada. No exemplo abaixo, o método responsável para fazer tudo isso será o RedirectUser.
public class TesteController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult Executar()
{
return View();
}
public ActionResult RedirectUser(string path)
{
//realiza o log
return Redirect(path);
}
}
Se acompanharmos o fluxo através de algum monitor de tráfego HTTP, veremos o redirecionamento sendo realizado. Vale lembrar que os redirecionamentos que estão sendo feitos aqui são realizados pelo navegados, exigindo o round-trip (código 302) entre o cliente e o serviço. Esse round-trip pode ser visualizado na imagem abaixo, através do ícone branco que está no segundo item da listagem.
Para facilitar estes cenários, o HTML 5 introduziu um novo atributo no elemetro <a /> chamando ping. Enquanto o atributo href deve ser o link de destino para o recurso desejado, o atributo ping servirá para apontar a ação que será utilizada para realizar o log quando o usuário clicar no respectivo link. A finalidade deste log vai ser, de fato, apenas catalogar o clique sem a necessidade de redirecionar o usuário para o local desejado/solicitado. Abaixo o exemplo de como configurar este atributo:
<a ping=”/Teste/Log” href=”/Teste/Executar”>Executar</a>
A imagem abaixo ilustra o procedimento em execução, postando assincronamente para o método Log enquanto também já encaminha o usuário para o destino clicado.
O interessante é que é realizado um POST para o método Log, incluindo várias informações extremamente relevantes, tais como a origem e o destino do ping, que podem ser capturadas pela ação de log para catalogar as informações das seções que foram solicitadas/acessadas. Abaixo temos as mensagens extraídas do Fiddler contendo os headers que foram enviados para o método Log neste exemplo, que faz uso também de um novo MIME que é o text/ping. O ponto negativo é que nem todos os navegadores implementaram este recurso. Infelizmente ele está somente implementando no Chrome e no Safari. Já há uma requisição aberta para que o time do Internet Explorer faça a adequação para suportar este atributo.
[ Requisição ]
POST http://localhost:17479/Teste/Log HTTP/1.1
Host: localhost:17479
Connection: keep-alive
Content-Length: 4
Cache-Control: max-age=0
Origin: null
Ping-From: http://localhost:17479/Teste/Index
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.117 Safari/537.36
Ping-To: http://localhost:17479/Teste/Executar
Content-Type: text/ping
Accept: */*
Accept-Encoding: gzip,deflate,sdch
Accept-Language: pt-BR,pt;q=0.8,en-US;q=0.6,en;q=0.4
PING
[ Resposta ]
HTTP/1.1 200 OK
Cache-Control: private
Server: Microsoft-IIS/8.0
X-AspNetMvc-Version: 5.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?QzpcVXNlcnNcSXNyYWVsXERlc2t0b3BcV2ViQXBwbGljYXRpb24xXFdlYkFwcGxpY2F0aW9uMVxUZXN0ZVxMb2c=?=
X-Powered-By: ASP.NET
Date: Wed, 26 Feb 2014 02:01:12 GMT
Content-Length: 0
Você comentou que o ping é enviado via post. Estaria esta feature a mercê do famigerado "deseja enviar as informações do formulário novamente" como seria o caso de dar um F5 no Browser logo depois de um post?