PHP: Como disponibilizar suas imagens/vídeos apenas para usuários autenticados

Nesse artigo irei mostrar como é possível evitar que pessoas sem autorização acessem suas imagens, vídeos, ou até mesmo arquivos do seu site.
Recentemente recebi um trabalho de um amigo no qual ele precisava desenvolver um sistema EaD (Educação a Distância) onde professores iriam fazer uploads de vídeos para suas aulas e cobrar para que alunos pudessem assisti-los. E aí é que me veio a pergunta: Se outra pessoa com o link do vídeo acessar, ele também poderá assistir mesmo sem autorização? Então, logo abaixo vamos entender como evitar esse tipo de situação.
Em nosso teste irei simular um ambiente onde um usuário não autenticado não poderá de nenhuma maneira obter acesso a uma imagem ou vídeo.
Segurança para imagens
Primeiro de tudo vamos configurar nosso arquivo .htaccess para que o Apache não permita o acesso direto às imagens.
.htaccess
RewriteEngine On
RewriteRule \.(jpg|jpeg|png)$ - [L,F]Com essa simples linha de código, nenhum visitante do seu site poderá acessar suas imagens pelo link direto.
Mas, e como vou fazer pra mostrar a imagem na página? Simples. Vamos criar um arquivo PHP que servirá para todas as imagens do site. Nesse arquivo vamos poder passar uma query $_GET dizendo qual imagem queremos mostrar. Em nosso código PHP, o que acontece é simples: O PHP vai primeiramente verificar se a requisição está vindo de um usuário autenticado para que ele forneça a imagem. Caso você não esteja autenticado, o PHP vai retornar um 404. Segue o código:
image.php
session_start();// Verifica se você está autenticado
if (isset($_SESSION['auth']))
{
// Aqui configura o header da resposta
// Não se esqueça de mudar o MIME type caso não for jpeg
// 'image.jpg' apenas para exemplificar
header('Content-Type: image/jpeg');
readfile('image.jpg');
}
else
{
header('HTTP/1.1 404');
}
Pronto! O seu servidor agora só fornecerá a imagem caso o usuário esteja autenticado.
Segurança para vídeos
O que veremos aqui será uma pequena diferença, já que o navegador não precisa baixar todo o vídeo para mostrar ao usuário. Queremos que o vídeo seja baixado aos poucos, por partes: assim não teríamos um consumo excessivo de banda e memória do nosso servidor e também evitaria o desgaste alheio da franquia de dados do nosso usuário móvel quando ele acionasse o play no vídeo.
Vamos trabalhar puramente com PHP e Apache. Não vamos utilizar nenhum módulo de terceiros para o Apache, como existe o X-Sendfile ‘recomendo utilizá-lo, caso tenha uma VPS ou servidor dedicado’ ou, se preferir, utilize o Nginx, pois já vem com esse módulo pré-instalado.
Então, ao .htaccess iremos inserir as seguintes linhas:
.htaccess
RewriteEngine On
RewriteCond %{HTTP_REFERER} !http://site.com.br/page/to/videos [NC]
RewriteRule \.(mp4|avi|mkv|mpeg|webm)$ - [L,F]Atenção para a linha !http://site.com.br/page/to/videos, pois é muito importante. Teremos que colocar a URL da página onde os vídeos serão mostrados. Caso o site tenha várias páginas diferentes que irão mostrar vídeos, sugiro utilizar regex nessa linha.
Agora o nosso arquivo PHP que irá verificar se o usuário está autenticado para fornecer o vídeo.
video.php
session_start();// Verifica se você está autenticado
if (isset($_SESSION['auth']))
{
// Aqui configura o header da resposta
// Não se esqueça de mudar o MIME type caso não for mp4
// 'video.mp4' apenas para exemplificar
header('Content-Type: video/mp4');
header('Location: video.mp4');
}
else
{
header('HTTP/1.1 404');
}
Perceba a linha header('Location: video.mp4');, pois o que acontece aqui é simplesmente criar um redirecionamento interno para que a gente possa simular que o usuário está pedindo o video.mp4 e não video.php.
Feito! Agora pra fazer com qualquer arquivo que não seja imagem e nem vídeo, basta seguir os mesmos passos que expliquei em Segurança para imagens.
Faça um teste acessando a aba Network do seu navegador e perceba como que o vídeo é carregado por pacotes, evitando o consumo excessivo de banda e memória do nosso servidor.
Um detalhe interessante nessa abordagem é o fato de que nem o próprio usuário autenticado poderá baixar os vídeos clicando com lado direito do mouse e depois em “Salvar vídeo…” ou acessando pelo link direto. Ele só poderá visualizá-los na página, nada além disso.
Bom, é isso!
