How to generate a nginx secure link in python

Question:

How do i make the link for the secure link module in nginx using python?
I’m looking to use nginx to serve secured files that have expiring links.
Link to Nginx Wiki

Asked By: Jharwood

||

Answers:

import base64
import hashlib

future = datetime.datetime.now() + datetime.timedelta(minutes=5)
url = "/securedir/file.txt"
timestamp = str(time.mktime(future.timetuple()))
security = base64.b64encode(hashlib.md5( secret ).digest()).replace('+', '-').replace('/', '_').replace("=", "")
data = str(url) + "?st=" + str(security) + "&e=" + str(timestamp)

data is your generated url of the form:

/securedir/file.txt?st=PIrEk4JX5gJPTGmvqJG41g&e=1324527723
Answered By: Jharwood

The accepted answer is incorrect because it only hashes the secret, not the combination of secret, url, and expiration time.

import base64
import hashlib
import calendar
import datetime

secret = "itsaSSEEECRET"
url = "/secure/email-from-your-mom.txt"

future = datetime.datetime.utcnow() + datetime.timedelta(minutes=5)
expiry = calendar.timegm(future.timetuple())

secure_link = "{key}{url}{expiry}".format(key=secret,
                                          url=url,
                                          expiry=expiry)
hash = hashlib.md5(secure_link).digest()
encoded_hash = base64.urlsafe_b64encode(hash).rstrip('=')

print url + "?st=" + encoded_hash + "&e=" + str(expiry)

Corresponding section of a nginx.conf

location /secure {

    # set connection secure link
    secure_link $arg_st,$arg_e;
    secure_link_md5 "itsaSSEEECRET$uri$secure_link_expires";

    # bad hash
    if ($secure_link = "") {
        return 403;
    }

    # link expired
    if ($secure_link = "0") {
        return 410;
    }

    # do something useful here
}
Answered By: shadfc

The code from shadfc’s answer works.
For Python 3, some modifications are necessary:

import base64
import hashlib
import calendar
import datetime

secret = "itsaSSEEECRET"
url = "/secure/email-from-your-mom.txt"

future = datetime.datetime.utcnow() + datetime.timedelta(minutes=5)
expiry = calendar.timegm(future.timetuple())

secure_link = f"{secret}{url}{expiry}".encode('utf-8')

hash = hashlib.md5(secure_link).digest()
base64_hash = base64.urlsafe_b64encode(hash)
str_hash = base64_hash.decode('utf-8').rstrip('=')

print(f"{url}?st={str_hash}&e={expiry}")
Answered By: flix
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.