2015-01-18 15 views
9

görebilirsiniz url sabitleyerek bir dosya gizli hale getirme.Nasıl o doğrulanmış değilken gizlenecek bir resim veya bir dosyayı güvenli bir yol olup olmadığını sadece doğrulanmış kullanıcılar merak ediyorum

o kullanıcı kimlik doğrulaması durumunda yalnızca görülebilir web sitemde bir resim bulunduğunu varsayalım. Ama şey şu ki, URL'yi kopyalayabilir veya görüntüyü yeni sekmede açabilirim.

http://siteis.com/media/uploaded_files/1421499811_82_Chrysanthemum.jpg

Ve yine, ben doğrulanmış değil bile, o url giderek o belirli görüntü elde edebilirsiniz. Yani, benim sorunum, dosyaları nasıl güvenli hale getirebilirim, böylece yalnızca kimliği doğrulanmış kullanıcılar görecek?

Güncelleme:

görünüm:

def pictures(request, user_id): 
    user = User.objects.get(id=user_id) 
    all = user.photo_set.all() 
    return render(request, 'pictures.html',{ 
     'pictures': all 
    }) 

modeller:

def get_upload_file_name(instance, filename): 
    return "uploaded_files/%s_%s" %(str(time()).replace('.','_'), filename) 

class Photo(models.Model): 
    photo_privacy = models.CharField(max_length=1,choices=PRIVACY, default='F') 
    user = models.ForeignKey(User) 
    image = models.ImageField(upload_to=get_upload_file_name) 

ayarları:

if DEBUG: 
    MEDIA_URL = '/media/' 
    STATIC_ROOT = os.path.join(os.path.dirname(BASE_DIR), "myproject", "static", "static-only") 
    MEDIA_ROOT = os.path.join(os.path.dirname(BASE_DIR), "myproject", "static", "media") 
    STATICFILES_DIRS = (
    os.path.join(os.path.dirname(BASE_DIR), "myproject", "static", "static"), 
    ) 

Güncelleme:

şablonu:

{% if pictures %} 
    {% for photo in pictures %} 
     <img src="/media/{{ photo.image }}" width="300" alt="{{ photo.caption }}"/> 
    {% endfor %} 
{% else %} 
    <p>You have no picture</p> 
{% endif %} 

url:

url(r'^(?P<user_name>[\[email protected]%.]+)/photos/$', 'pictures.views.photos', name='photos'), 

if settings.DEBUG: 
    urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) 
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) 
+1

dosya adlarını sterilize nasıl bir düşünce için django.views.static.serve edin Bir yolu denetleyici URL işlemek '/ media/uploaded_files/*' ve kimlik bilgilerini kontrol etmesi olacaktır. Yetkili değilse, bir 404 durumu döndürün. – Javier

+0

@Javier Lütfen güncellemeye bir göz atabilir ve nasıl yapılacağını önerebilir misiniz? Teşekkür ederim. – Robin

+0

Dosyaların URL'si artık statik bir parçası değil, mantıksal bir URL olmalıdır. Ve sonra Şeyhan Khalid'ın yayınladığı şeye benzer bir şey yaparım. – Javier

cevap

7

mous kullanıcısı, daha iyi yol url koruması.

Kodu (Güncellendi):

from django.conf.urls import patterns, include, url 
from django.contrib.auth.decorators import login_required 
from django.views.static import serve 
from django.conf import settings 

from django.core.exceptions import ObjectDoesNotExist 
from django.shortcuts import HttpResponse 

@login_required 
def protected_serve(request, path, document_root=None): 
    try: 
     obj = Photobox.objects.get(user=request.user.id) 
     obj_image_url = obj.image.url 
     correct_image_url = obj_image_url.replace("/media/", "") 
     if correct_image_url == path: 
      return serve(request, path, document_root) 
    except ObjectDoesNotExist: 
     return HttpResponse("Sorry you don't have permission to access this file") 


url(r'^{}(?P<path>.*)$'.format(settings.MEDIA_URL[1:]), protected_serve, {'file_root': settings.MEDIA_ROOT}), 

Not: Daha önce herhangi ... şimdi bu güncelleştirme diğer dosyaları görüntülemek için sigara kullanıcıyı kısıtlamak, herhangi bir sayfayı erişebilir giriş yapan kullanıcılar

+0

Ayrıca, şablondaki fotoğrafları nasıl gösterebilirim? Bunu gerçekten takdir edeceğim. Teşekkür ederim. – Robin

+1

Evet, çalışma kodum var. Ve bana şablondaki fotoğrafı gösteriyor. Şey, resmin URL'sini kopyalayabilir ve anonim kullanıcı olarak açabilirim. Kodunuzu denedim, görüşlerinizi ve URL'nizi kopyaladım. Ama hiçbir şey değişmedi. Daha fazla detaylandırırsanız seviniriz. – Robin

+0

Harika! Şimdi çalışıyor! Teşekkür ederim! – Robin

1

kolay seçenek django dosyayı hizmet ve daha sonra bu gibi görünüme @login_required decorator eklemektir:

herhangi bir medya dosyasını anony tarafından hizmet etmek değil güvence olarak
import os 
import mimetypes 
from django.core.servers.basehttp import FileWrapper 
from django.contrib.auth.decorators import login_required 

@login_required 
def sekret_view(request, path=None): 
    filename = os.path.basename(path) 
    response = HttpResponse(FileWrapper(open(path)), 
          content_type=mimetypes.guess_type(path)[0]) 
    response['Content-Length'] = os.path.getsize(path) 
    return response 
+0

Cevabınız için teşekkür ederiz. Ama django'nun şablonda nasıl gösterileceğine dair fazla bir şey elde edemedim. Belki eğer yapabilirseniz, güncellemeye bir göz atın ve nasıl olduğunu söyleyin, çok minnettar olacağım. – Robin

1

O olurdu Sadece kimlik doğrulamayı işlemek için daha iyi ve web sunucunuzun dosyaların sunumunu yapmasına izin verin. Web sunucunuzun, dosyayı işleme koymadan önce dosyaları sunmasını engellemek için onları settings.MEDIA_ROOT'dan farklı bir dizine koymanız iyi bir olasılıktır, örn. project_root/web-private/media/. web sunucunuza olarak

import os 

@login_required 
def protected_file(request, path): 
    # set PRIVATE_MEDIA_ROOT to the root folder of your private media files 
    name = os.path.join(settings.PRIVATE_MEDIA_ROOT, path) 
    if not os.path.isfile(name): 
     raise Http404("File not found.") 

    # set PRIVATE_MEDIA_USE_XSENDFILE in your deployment-specific settings file 
    # should be false for development, true when your webserver supports xsendfile 
    if settings.PRIVATE_MEDIA_USE_XSENDFILE: 
     response = HttpResponse() 
     response['X-Accel-Redirect'] = filename # Nginx 
     response['X-Sendfile'] = filename # Apache 2 with mod-xsendfile 
     del response['Content-Type'] # let webserver regenerate this 
     return response 
    else: 
     # fallback method 
     from django.views.static import serve 
     return serve(request, path, settings.PRIVATE_MEDIA_ROOT) 

Django daha statik sunum dosyalarını yol daha iyi olduğunu, bu web sitenizi hızlandırır. vb

+0

Bu yöntemi kullanmak için, Apache 2 yapılandırmasında herhangi bir şeyi değiştirmem gerekir mi? –

+1

@RenelChesak Bunu çoğunlukla Ngnix ile kullanıyorum. Apache'de mod_xsendfile'ı yüklemeniz ve etkinleştirmeniz gerekebilir, ancak detaylarda emin değilim. – knbk

+0

Bu, Apache'yi kurmak için çok yararlı bir öğreticidir: https://www.h3xed.com/web-development/how-to-install-xsendfile-mod-xsendfile-apache-vps-web-host. Yukarıdaki kod için @knbk, bu ana projenin urls.py içinde olması gerekir mi yoksa app'ın view.py işlevine Dayalı Görünüm olması mı gerekiyor? –