How to provide temporary download url in Flask? How to provide temporary download url in Flask? flask flask

How to provide temporary download url in Flask?


The best way to do that is to use itsdangerous package. You can generate a URL that last whatever time you want. Furthermore you could encode secretly any information within the URL. The good thing about that is that NO need to deal or store timestamps into the database

To generate a URL that last for 30 mins and encode user id within the token

from itsdangerous import TimedJSONWebSignatureSerializer as Serializers = Serializer('WEBSITE_SECRET_KEY', 60*30) # 60 secs by 30 minstoken = s.dumps({'user_id': currentuser.id}).decode('utf-8') # encode user id 

Use the following to generate the URL you want

url_for('get_file', token=token)

To validate a URL

@app.route('/get_file/<token>')def get_file(token):    s = Serializer('WEBSITE_SECRET_KEY')    try:        user_id = s.loads(token)['user_id']    except:        return None    user = User.query.get(user_id)    if not user:        flash('This is an invalid or expired URL, please generate a new one!', 'warning')        return redirect(url_for('another_route'))    return send_from_directory('static', filename, as_attachment=True)


There are a couple ways you can do this.

  1. Generate a UUID for your token and store it in a db table along with the desired expiration datetime. Then when someone calls the URL with the token, you can just check it against the db for validity and expiration.

  2. If you don't want to use a db to store the tokens, you can use GPG to encrypt a string that contains the expiration datetime and use the resulting encrypted string as your token. This means your token will be a lot longer than a UUID, but you'd avoid having to use a db.

I recommend using UUID and a db table.


Maybe you should use hmac.

Generate link

import hashlibimport hmacimport timesecret = "anything you like"  # such as generate from os.urandom(length)def generate(filename):    current_time = str(int(time.time()))    token = hmac.new(secret, current_time, hashlib.sha256).hexdigest()    return "get_file?file=%(filename)s&time=%(current_time)s&token=%(token)s" % {        "filename": filename,        "current_time": current_time,        "token": token    }

Verify link

import hashlibimport hmacimport timesecret = "anything you like"  # same as in generate functiondef verify(time_in_link, token_in_link):    time_limit = 15 * 60  # maximum time in sec(such as: 15(mins) * 60 (convert them to sec)`enter code here`) that you want them to start download after the link has been generated.    if (time.time() - int(time_in_link)) > time_limit:  #timeout, return False        return False    if hmac.new(secret, str(time_in_link), hashlib.sha256).hexdigest() == token_in_link:  # Check the token is available or not        return True    else:        return False