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 Serializer
s = Serializer('WEBSITE_SECRET_KEY', 60*30) # 60 secs by 30 mins
token = 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.
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.
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.