محافظت از موضوع‌های یک کاربر

ما هنوز دسترسی به صفحه‌های موضوعات را محدود نکرده‌ایم در نتیجه هر کاربری که ثبت نام کرده باشد می‌تواند تعدادی آدرس به شکل http://localhost:8000/topics/1/ را امتحان کند تا بالاخره به یکی از صفحه‌ها با شماره‌ی موجود دست یابد.

این را خودتان امتحان کنید. در حالی‌که با حساب کاربری کسی که مالک تمام موضوع‌هاست وارد شده‌اید، آدرس یکی از موضوع‌ها را کپی کنید یا شماره‌ی آن را یادداشت کنید. سپس از سیستم خارج شوید و با کاربری دیگری وارد شوید. آدرس آن موضوع را وارد کنید. باید قادر باشید که مطالب آن را بخواهید هرچند که آن‌ها به کاربری دیگری تعلّق دارند.

این مشکل با انجام یک بررسی پیش از دریافت مطالب درخواستی در تابع نمای topic() برطرف می‌کنیم:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
from django.shortcuts import render, redirect

from django.contrib.auth.decorators import login_required
from django.http import Http404

--snip--

@login_required
def topic(request, topic_id):
    """Show a single topic and all its entries."""
    topic = Topic.objects.get(id=topic_id)
    # Make sure the topic belongs to the current user.
    if topic.owner != request.user:
        raise Http404

    entries = topic.entry_set.order_by('-date_added')
    context = {'topic': topic, 'entries': entries}
    return render(request, 'learning_logs/topic.html', context)

--snip--

پاسخ 404 یک پیام خطای استاندارد است و هنگامی برگردانده می‌شود که محتوای درخواستی روی سرور وجود نداشته باشد. اینجا استثنای Http404 را وارد می‌کنیم (۱) که اگر کاربر موضوعی را درخواست کند و آن وجود نداشته باشد، اعلام می‌شود. پس از دریافت درخواست و پیش از تولید صفحه کاربر مطمئن می‌شویم که کاربر مرتبط با آن موضوع با کاربری که الان وارد شده مطابقت دارد یا نه. اگر کاربر فعلی مالک موضوع درخواستی نبود استثنای Http404 را اعلام می‌کنیم (۲) و جانگو صفحه‌ی خطای 404 را برمی‌گرداند.

اکنون اگر تلاش کنید که مطالب مربوط به موضوع کاربری دیگری را ببینید پیام Page Not Found را از سوی جانگو خواهید دید. در فصل ۲۰ پروژه را جوری تنظیم می‌کنیم که یک صفحه‌ی خطای مناسب نمایش داده شود.

محافظت از صفحه‌ی edit_entry

صفحه‌های edit_entry آدرسی به شکل http://localhost:8000/edit_entry/entry_id/ هستند که entry_id یک عدد است. بیایید از این صفحه محافظت کنیم تا هیچ‌کس نتواند از این آدرس برای دست یافتن به مطالب کس دیگری استفاده کند:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
--snip--

@login_required
def edit_entry(request, entry_id):
    """Edit an existing entry."""
    entry = Entry.objects.get(id=entry_id)
    topic = entry.topic
    if topic.owner != request.user:
        raise Http404

    if request.method != 'POST':
        --snip--

مطلب و موضوع مربوط به آن را دریافت می‌کنیم. سپس بررسی می‌کنیم که آیا صاحب این موضوع کاربری است که الان وارد شده یا نه؛ اگر چنین نبود استثنای Http404 را اعلام می‌کنیم.