Skip to main content

Proxyid hides your Django model primary key

Project description

Proxyid

Proxyid hides your Django model primary key

Proxyid turns https://myapp.com/model/1 into https://myapp.com/model/5NxJD1dG6V

It makes use of the hashids library to mask your integer or uuid based primary keys. It's plug'n play, therefore, it doesn't interfere with the database or model definitions.

Type Primary Key Exposed Proxied PK
Integer 3 5NxJD1dG6VB3ZR3eKyzYEWrba
UUID 82df2e8e-553b-4330-bd46-8299ec67a9bb 7ljjRD1qVLfjkQepdRZAimyDDZZ2

Quick Start

Assuming a Django project is already set with an app called appmock, proxyid can be installed with pip.

$ pip install proxyid

The configuration is set as a constant PROXYID in settings.py

PROXYID = {
    "hashids": {
        "salt": "A grain of salt", # this is your salt
        "min_length": 15           # this is the minimum length of the proxied id
    }
}

Let's say the project has an Author model

# djangoproject/appmock/models.py
from django.db import models

class Author(models.Model):
    name = models.CharField()
    nationality = models.CharField()

    def __str__(self):
        return self.name

Now take a look at our urls.py

# djangoproject/appmock/urls.py
from django.urls import path
from appmock import views


urlpatterns = [
    # ...other path configuration
    # ...other path configuration
    # ...other path configuration
    path("author/<pk>/", views.author_detail, name="author-detail")
]

Proxify the Primary Key

If the app is exposing the database's primary key, the Author resource would be found, for example, at http://myapp.com/author/1 Let's hide our primary key. by importing the proxify decorator and defining a property method.

# djangoproject/appmock/models.py
from django.db import models
from proxyid.decorators import proxify

class Author(models.Model):
    name = models.CharField()
    nationality = models.CharField()

    @property
    @proxify
    def id_(self): pass

    def __str__(self):
        return self.name

That's it, now our model instance will have the id_ property with it's unique primary key encoded by proxyid by using the hashids library. All we need is a method which doesn't return anything and the decorators @property and @proxify. You can name this property method whatever you want(except pk or id), let's name it id_ for this example.

Let's check it by retrieving a model in a django shell session

$ python manage.py shell
Python 3.9.2 (default, Mar 21 2021, 20:35:03)
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from appmock import models
>>> author = models.Author.object.create(name="Lima Barreto", nationality="Brazil")
>>> author.id
1
>>> author.id_
RvBykxK6qojOJnOMrQeGpALDW

Retrieving objects from encoded Primary Keys

Now, how about retrieving our object from the database if our user is giving us the encoded(RvBykxK6qojOJnOMrQeGpALDW) primary key? Let's go to our hypothetical author_detail view function in views.py

# djangoprojects/appmock/views.py
from django.shortcuts import render, HttpResponse

from appmock.models import Author

from proxyid.encoding import decode

# ...other code

def author_detail(request, pk):
    decoded_pk = decode(pk) # this will bring RvBykxK6qojOJnOMrQeGpALDW back to 1
    author = Author.objects.get(pk=decoded_pk)
    context = {"author" : author}
    return render(request, "appmock/author_detail.html", context)

We imported decode from proxyid.encoding, the decode function will transform our proxied value back to it's original primary key value, allowing us to retrieve our object by giving the pk value to the ORM.

How the urls were generated? By just passing the object id_ instead of pk property or whatever name you have it to the url function. Like this:

<!-- some html -->

{% url 'author-detail' author.id_ %}

Now our author resource can be found at http:myapp.com/author/RvBykxK6qojOJnOMrQeGpALDW

What about class based views?

Let's build the same logic of author_detail function view as a class based view now:

# djangoproject/appmock/views.py
from django.views import generic

from appmock.models import Author

from proxyid.mixins import ProxyidMixin

class AuthorDetailView(ProxyidMixin, generic.DetailView):
    template_name = "appmock/author_detail.html"
    model = Author
    context_object_name = "author"

That's it, the view will work the same way as long as you use the ProxyidMixin as a parent class, and don't forget to provide a pk argument(this can be customized) from the url dispatcher.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

proxyid-0.1.0.tar.gz (7.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

proxyid-0.1.0-py3-none-any.whl (7.7 kB view details)

Uploaded Python 3

File details

Details for the file proxyid-0.1.0.tar.gz.

File metadata

  • Download URL: proxyid-0.1.0.tar.gz
  • Upload date:
  • Size: 7.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/3.7.3 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.59.0 CPython/3.9.2

File hashes

Hashes for proxyid-0.1.0.tar.gz
Algorithm Hash digest
SHA256 de74c041b231122d63992ac9755804c10f46d2d0f923a403a0282ac137d8a521
MD5 acc7b16f3d4f0d45b49beaf2e784bfb1
BLAKE2b-256 d9bc123a50fc28f2ee16da3ffdcca244ddadc19ef12e3c6317a633d15723009d

See more details on using hashes here.

File details

Details for the file proxyid-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: proxyid-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 7.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/3.7.3 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.59.0 CPython/3.9.2

File hashes

Hashes for proxyid-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6df505cdb07c1b4a87a548df49440a0e3cf11c2839bbe3b57bcce55958463a9f
MD5 9fcc0197b1e77368d2dff83c88df8738
BLAKE2b-256 57790020b6a1346003c46b9448078ae2da47b8b87677f9baeee6cd8ecbc6a10d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page