Pular para o conteúdo

Controle de Acesso ao Servir Arquivos com Django/Python

Dica publicada em Python / Django
Thiago Silva pain-sama
Hits: 3.085 Categoria: Python Subcategoria: Django
  • Indicar
  • Impressora
  • Denunciar
O Viva o Linux depende da receita de anúncios para se manter. Ative os cookies aqui para nos patrocinar.
Não conseguimos carregar os anúncios. Se usa bloqueador, considere liberar o Viva o Linux para nos patrocinar.

Controle de Acesso ao Servir Arquivos com Django/Python

Resolvi falar disso porque vi pela internet que isso é uma questão bem recorrente para quem desenvolve em Python com Django. A forma "normal" de servir arquivos seria declarando o MEDIA_ROOT no seu settings.py e adicionando a rota em urls.py, certo?

Bom, isso funciona, mas qualquer um pode acessar os arquivos lá. Digamos que sua pasta MEDIA fosse "uploads" e houvesse um arquivo com o nome "user_profile1_image.png", então QUALQUER UM que digitasse no navegador http://<seu domínio ou ip>/uploads/user_profile1_image.png veria a imagem. Quando se lida com arquivos sensíveis, isso não é nada bom.

Como resolver isso?

Primeiramente, existem várias formas de se resolver essa questão. A maioria delas vai deixar o serviço por conta do Django. Mas além de aumentar o tamanho do código, pode também sobrecarregar o servidor, a depender. Em vez disso, você pode usar o seu próprio servidor para isso, de um jeito bem fácil, aliás. Aqui mostrarei como usar o Nginx para isso, mas é possível fazer algo parecido com o Apache também.

Mão na massa!

É bem simples. Siga até o arquivo de configuração do Nginx, em que o seu servidor foi configurado. Provavelmente...

nano /etc/nginx/sites-enabled/SEU_PROJETO

...deve te levar até lá. Você agora só precisa adicionar no bloco "server" o seguinte:

location /ARQUIVOS/ {
          internal;
          root /home/USER/PROJETO;
   }
O Viva o Linux depende da receita de anúncios para se manter. Ative os cookies aqui para nos patrocinar.
Não conseguimos carregar os anúncios. Se usa bloqueador, considere liberar o Viva o Linux para nos patrocinar.

Onde ARQUIVOS é o nome da pasta a ser protegida e root /home/USER/PROJETO; é o caminho COMPLETO até a pasta raiz do seu projeto. Salve e feche.

Não é preciso fazer nada em settings.py, não adicione a pasta como MEDIA_ROOT e se você já fez isso, retire essa configuração.

Em urls.py crie uma rota para uma view como qualquer outra. Como exemplo,

urlpatterns = [
      ...,
      path('file/', require_files),
      ...
]

Em views.py do app que vai consumir esses arquivos, crie a função:

def require_files(request):
        if request.user.is_staff:
             response = HttpResponse(status=200)
             response['Content-Type'] = ""
             response['X-Accel-Redirect'] = request.path
             return response

Perceba que alteramos o cabeçalho da resposta. É exatamente essa alteração que permite ao Nginx saber se deve ou não servir determinado arquivo. Nesse caso, apenas o pessoal da staff poderá acessá-los, mas com essa lógica você tem total liberdade para controlar a view que dará permissão de acesso como você bem quiser.

Por exemplo, se existe o model Pedido com um arquivo enviado pelo usuário e ele queira acessar, a sua view seria algo parecido com isso:

@login_required(login_url="/login/")
def require_files(request, id):
        # Isso limitará a pesquisa ao usuário então se ele der um jeito de mandar o id de um pedido de outro usuário
        # será negado
        pedido = Pedido.objects.filter(id=id,user_id=request.user.id)
        # Garante que o pedido existe
        if pedido:
             response = HttpResponse(status=200)
             response['Content-Type'] = ""
             response['X-Accel-Redirect'] = '/' + pedido[0].arquivo
             return response

É isso, pessoal, até mais!

O Viva o Linux depende da receita de anúncios para se manter. Ative os cookies aqui para nos patrocinar.
Não conseguimos carregar os anúncios. Se usa bloqueador, considere liberar o Viva o Linux para nos patrocinar.

Executar Script na Inicialização do Sistema com Systemd

Instalação do OpenOffice no Arch Linux

Dash to Dock no Gnome 3.34

Remover pedido de senha para Chaveiro de Sessão

Spotify no Arch Linux

Python e Visual Studio Code no Debian

Usando o MySQL no Python

Reproduzindo vídeos em modo texto no Linux

Programação funcional em Python

Como encerrar um script Python (exit)

Nenhum comentário foi encontrado.

Contribuir com comentário

Entre na sua conta para comentar.