2012-06-27 2 views
1

Извините, я до сих пор новичок в Django, надеюсь, вопрос не неуместен.Как ограничить редактирование записей зарегистрированному пользователю?

Когда у меня есть следующие в моем шаблоне:

<td><a href="/contact/edit/?id{{ item.id }}">{{ item.last_name }}</a></td> 

Нажав на фамилию пользователя будет перенаправлен на следующую ссылку, чтобы изменить его.

http://127.0.0.1:8000/contact/edit/?id=1 

Но что мешает любой зарегистрированный пользователь просто впрыснуть другой идентификатор там в браузере и редактировать запись, которая не принадлежит ему?

Update

Я просто была идея, когда я прочитал комментарий и ответить ниже. Вместо того, чтобы использовать стороннее приложение, я не могу просто создать UserProfile для каждого пользователя и прикрепить уникальную компанию uuid.uuid1(). Каждый раз, когда пользователь loggedin пытается что-то редактировать, его уникальная компания uuid также будет передана по ссылке в качестве дополнительного параметра.

На стороне редактирования он собирает это руководство и сравнивает его с зарегистрированным пользователем и видит, совпадают ли они. Если они совпадают, он имеет право продолжить редактирование, иначе он будет перенаправлен.

Как вы думаете? Какие-нибудь недостатки?

+0

На странице с формой.save() на странице редактирования вам необходимо проверить, имеются ли у пользователя разрешения на редактирование этого пользователя. Вы не можете заставить их не изменять URL-адрес ... Или на странице загрузки страницы редактирования, чтобы проверять разрешения и перенаправлять при необходимости ... – Tisho

+0

Да, это хорошая идея. У меня есть предложение. Проверьте мой обновленный вопрос. Как вы думаете? – Houman

+0

Почему бы просто не проверить разрешение в представлении формы и не разрешить любую неавторизованную операцию, это стандартное использование IMO – okm

ответ

0

Когда вы используете Django auth, всегда полагаются на механизм session для идентификации пользователя вместо того, чтобы какой-либо другой идентификатор, например, как uuid1() (за исключением, например, когда требуются дополнительные сеансы в сайт электронной коммерции под HTTPS).

Для части разрешения вы можете проверить право собственности непосредственно, в основном, как описано в Koliber Services. Отношения между Company, User и Contact имеют решающее значение для логики проверки разрешений. Существует много способов моделирования отношений, и, следовательно, код будет сильно отличаться. Например:

# a modeling way 
User.company -> Company : an user belongs to a company 
Contact.contributor -> User : a contact is contributed by an user, would be invalid is user is leaving the company 
# could check accessibility by 
can_view = contact.contributor.company_id == current_user.company_id 

# another modeling way 
User.company -> Company : an user belongs to a company 
Contact.company -> Company : a contact info is owned by a company, does not share globally 
# could check accessibility by 
can_view = contact.company_id == current_user.company_id 

Когда can_view является False, пользователь должен получить 403 для его несанкционированного попытки и получить журнал.

Обычно вышеуказанного метода достаточно для защиты контента (еще не в Django Admin). Однако, когда у вас есть много разных типов проверки разрешений и даже проверки разрешений на строки, лучше использовать некоторый единообразный API разрешений.

Возьмите, к примеру, администратора Django, вы можете просто сопоставить компании с группами и assigncan_view разрешение на контакт для группы, представляющей компанию пользователя. Или, assigncan_view разрешение для всех пользователей в компании, когда контакт создается с помощью сигнала или задачи сельдерея.

Кроме того, вы можете использовать /contact/1/edit/ вместо /contact/edit/?id=1. Таким образом, часть int(request.GET('id')) перемещается в urlconf как r'^contact/(?P<pk>\d+)/$', меньше кода и намного понятнее.

0

Есть некоторые сторонние приложения, которые делают то, что вы хотите, его называете «разрешение на уровне строк», где вы можете предоставить различным пользователям различный доступ к определенным объектам, «Уровень строки» поступает из SQL, где каждый объект является строкой в базе данных

Я использую django-guardian, чтобы сделать работу

+0

Благодарим вас за ответ. Ты просто дал мне идею. Я обновил вопрос. – Houman

0

в функции обработки сохранение данных, проверьте, чтобы увидеть, если объект редактируемого имеет тот же идентификатор, как в настоящее время вошли в систему.

Например, если рассматриваемый объект называется EmailPrefs и имеет поле под названием user_id:

  1. зарядите EmailPrefs объект с идентификатором объекта редактируемого
  2. Если user_id не соответствует текущий пользователь, остановка Дальнейшая обработка
  3. Измените EmailPrefs объект
  4. Сохраните EmailPrefs объект в базе данных
+0

Очень хорошо. Я думаю, что это даже лучше, чем идея, которую я предложил. Поскольку вам больше не нужно будет передавать идентификатор в качестве дополнительного параметра и будет автоматически проверять его за кулисами.Поэтому при создании любого экземпляра любой модели в объект должен храниться дополнительное поле с user_id. И при редактировании объекта этот идентификатор должен соответствовать одному из зарегистрированных пользователей, чтобы продолжить. Правильно ли я понял вас? – Houman

2

Если вы используете новый Django class based views, например. общий UpdateView, вы можете расширить обработчик dispatch.

def dispatch(self, request, *args, **kwargs): 
    handler = super(MyEditView, self).dispatch(request, *args, **kwargs) 
    # Only allow editing if current user is owner 
    if self.object.author != request.user: 
     return HttpResponseForbidden(u"Can't touch this.") 
    return handler 

В этом случае код проверяет, что author поле модели объекта соответствует вошедшего в систему пользователя, прежде чем даже обработки остальной части запроса.

Вы можете увидеть пример reallife этого в project of mine.

+0

Это отличное решение, по крайней мере, это сработало для меня в любом случае. ;-) – Patrick

Смежные вопросы