1

There are URLs which I use only for redirecting a user after a successful operation. (e.g. Thank you page after submitting feedback).

Problem is that these pages can be accessed directly.

Is there a way to prevent this?

Thanks

AmirW
  • 816
  • 9
  • 20
  • 1
    You could [check the referrer](http://stackoverflow.com/a/4406484/344821) from the HTTP request. – Danica Aug 13 '12 at 22:06
  • Thank you. But I think this is too low level. I'd prefer a solution which doesn't involve looking at the HTTP headers. (e.g. a django decorator?) – AmirW Aug 13 '12 at 22:22
  • And what you expect when a user tries to access a such page? – sergzach Aug 13 '12 at 22:54
  • Best thing is if the behavior is flexible and programmable. next best is a 404 or 403. – AmirW Aug 13 '12 at 23:00

4 Answers4

3

The URL is handled by a view, so make sure the view is only happy if the last thing it did was a successful operation for the logged-in user. Otherwise raise Http404.

Just do this by checking the session variable for the user in the view. The logic goes something like:

shop.html: user hits 'post' to buy.html

view for buy.html bills the user, sets 'just bought something' in session, redirects to thanks.html

view for thanks.html checks for 'just bought something' session variable, clears it if set otherwise 404, and renders a template to the response on success.

Spacedman
  • 92,590
  • 12
  • 140
  • 224
1

I suggest the message framework for doing this.

Danica
  • 28,423
  • 6
  • 90
  • 122
fabiocerqueira
  • 762
  • 4
  • 12
  • 1
    Nice direction. It's not the intended use of messages though. AFAIK messages framework is used to display messages and not to communicate general pieces of information between pages. But I think I like it :) – AmirW Aug 13 '12 at 23:10
  • @fabiocerqueira, me thinks, your hack is a bad one. Because if any changes are implemented in the messages API (such unqualified hacks will not be considered) causing the code to be broken. As a principle its always good to use API's the way they were intended for what they were intended for. – unlockme Aug 22 '16 at 09:46
1

You could do something very simple in the view like redirect if the the user doesn't provide a particular GET parameter:

if not request.GET.get('show', False):
     # do redirection
else:
     # render the page

so the URL can only be accessed with /my-url/?show=true

Timmy O'Mahony
  • 53,000
  • 18
  • 155
  • 177
1
def get_referer(request):
    referer = request.META.get('HTTP_REFERER')
    if not referer:
        return None
    return referer

Then in any view:

def my_view(request):
    if not get_referer(request):
        raise Http404
    return render(request, 'sample.html', {})

Here we'll be assuming that if there's no referer (None), it means the person typed in the URL into the browser.

aqpcserver
  • 66
  • 7