我想为我的用户生成临时下载链接。 如果我使用django使用url模式生成链接,那可以吗? 这可能是正确的方法。因为可能发生我不理解某些过程如何工作。它会溢出我的记忆或其他东西。将会欣赏某种示例或工具。有些nginx,apache模块可能吗?
所以,我想要实现的是制作依赖于用户和时间的网址模式。在文档中查看结束返回。
答案 0 :(得分:4)
一个简单的方案可能是使用用户名和时间戳的哈希摘要:
from datetime import datetime
from hashlib import sha1
user = 'bob'
time = datetime.now().isoformat()
plain = user + '\0' + time
token = sha1(plain)
print token.hexdigest()
"1e2c5078bd0de12a79d1a49255a9bff9737aa4a4"
接下来,将该令牌存储在具有过期时间的内存缓存中。这样,您的任何网络服务器都可以访问它,令牌将自动过期。最后为'^ download /.+'添加一个Django url处理程序,其中控制器只在memcache中查找该令牌以确定令牌是否有效。您甚至可以将要下载的文件名存储为memcache中的标记值。
答案 1 :(得分:2)
是的,允许django生成网址是可以的。这与urls.py处理网址是排他的。通常你不希望django处理文件的服务,请参阅关于此的静态文件docs [1],因此请从头脑中获取使用url模式的概念。
您可能想要做的是使用哈希生成随机密钥,例如md5 / sha1。存储文件和密钥,它在数据库中添加的日期时间,在您的网络服务器上可以创建下载目录,如apache或nginx ...建议nginx),因为它是临时的,你需要添加一个cron检查自生成url以来的时间是否已过期的作业,清除文件并删除db条目。这应该是manage.py
的django命令请注意这是为此编写的示例代码,未经测试!它可能无法按照您计划实现此目标的方式运行,但它可行。如果你想让dl受到pw保护,那么请查看httpbasic auth。您可以在创建链接时或在注册时使用htpasswd和子进程模块在httpd.auth文件中动态生成和删除条目。
import hashlib, random, datetime, os, shutil
# model to hold link info. has these fields: key (charfield), filepath (filepathfield)
# datetime (datetimefield), url (charfield), orgpath (filepathfield of the orignal path
# or a foreignkey to the files model.
from models import MyDlLink
# settings.py for the app
from myapp import settings as myapp_settings
# full path and name of file to dl.
def genUrl(filepath):
# create a onetime salt for randomness
salt = ''.join(['{0}'.format(random.randrange(10) for i in range(10)])
key = hashlib('{0}{1}'.format(salt, filepath).hexdigest()
newpath = os.path.join(myapp_settings.DL_ROOT, key)
shutil.copy2(fname, newpath)
newlink = MyDlink()
newlink.key = key
newlink.date = datetime.datetime.now()
newlink.orgpath = filepath
newlink.newpath = newpath
newlink.url = "{0}/{1}/{2}".format(myapp_settings.DL_URL, key, os.path.basename(fname))
newlink.save()
return newlink
# in commands
def check_url_expired():
maxage = datetime.timedelta(days=7)
now = datetime.datetime.now()
for link in MyDlink.objects.all():
if(now - link.date) > maxage:
os.path.remove(link.newpath)
link.delete()
[1] http://docs.djangoproject.com/en/1.2/howto/static-files/
答案 2 :(得分:1)
听起来你建议使用某种动态网址。
为什么不通过简化和设置一个捕获依赖于用户/时间的大型编码字符串的网址来忘记您的顾虑?
(r'^download/(?P<encrypted_id>(.*)/$', 'download_file'), # use your own regexp
def download_file(request, encrypted_id):
decrypted = decrypt(encrypted_id)
_file = get_file(decrypted)
return _file
许多网站也使用了get param。
www.example.com/download_file/?09248903483o8a908423028a0df8032
突出显示apache x-sendfile模块的使用。
另一种选择是简单地重定向到django提供的静态文件。