from django.shortcuts import resolve_url from django.core.signing import Signer from django.core.exceptions import SuspiciousOperation signer = Signer() import logging logger = logging.getLogger(__name__) def sign_data(data, l=None): sig = signer.sign(data) p = len(data) + 1 if l: l += p return sig[p:l] def signed_url(name, **kwargs): """ >>> signed_url('foo/bar') """ url = resolve_url(name, **kwargs) sig = signer.sign(url) sep = "&" if "?" in url else "?" return sig.replace(":", f"{sep}auth=") def check_signed_url(full_path): p = full_path.rfind('auth') url = full_path[:p-1] logger.debug("check_signed_url: %s", url) signed = signed_url(url) if signed != full_path: logger.debug("Mismatch: %s != %s", full_path, signed) signed = "_HIDDEN_" raise SuspiciousOperation("Bad auth code") if __name__ == '__main__': import doctest print(doctest.testmod())