url design: ways to hide pk/id from url

11,607

Solution 1

You need to have some kind of identifier in the URL, and this identifier:

  1. must be unique (no two objects can have the same id)
  2. must be permanent (the id for an object can never change)

so there aren't all that many options, and the object's primary key is the best choice. If for some reason you can't use that (why not?) you can encode or obfuscate it: see this question and its answers for some ideas about how to do that.

Stack Overflow's own URL design is worth a look. You can reach this question via any URL of the form

https://stackoverflow.com/questions/9897050/any-text-you-like-here!

This allows the URL to contain keywords from the question's title (for search engines) while also being able to change when the title changes without breaking old links.

Solution 2

I don't like the slugfield option because it adds an additional query to the database.

I did the following in a project:

My URL looks like this:

<domain>/item/5927/728e26e9464a171b228bc9884ba3e4f76e2f8866/

This is:

<domain>/item/<id>/<hash>/

If you don't know the hash you can't get to the item:

urls.py:

url(r'^item/(?P<id>\d+)/(?P<hash>\w+)/$', 'rwapp.views.item', name='item')

views.py:

from hashlib import sha1

def item(request,id=None,hash=None):
    if not id:
        return HttpResponseRedirect("/home")
    if hash:
        chash = sha1("secret_word%s"%id).hexdigest()
        if not chash==hash:
            return HttpResponseRedirect("/home")
    else:
        return HttpResponseRedirect("/home")

Of course, every time you render the URL you have to add the // part.

Solution 3

For Django, you can give your models a SlugField, then have the view look up the model using that.

MyModel.objects.filter(slug_field_name='some-slug-value')

Make sure some form of uniqueness constraint is on it.

Solution 4

Well there are a lot ways to do this. Since you are using django, take a look at SlugField. Or you generate UUID and store it on each item for access.

Share:
11,607
tamakisquare
Author by

tamakisquare

Updated on June 18, 2022

Comments

  • tamakisquare
    tamakisquare almost 2 years

    To access the details page of an Item on my site, one would use the following url

    <mydomain>/item/1
    

    where 1 is the primary key of the Item

    I am looking for a solution that allows me to redesign the url with the following requirements:

    • exclude pk or any sequential ids from the url
    • be able to uniquely access the Item details page

    I intended to ask this as a general web design question, but just thought I should mention that I am working with Python/Django.