Как запретить вошедшему в систему пользователю получить доступ к профилю другого пользователя, просто изменив идентификатор в url, в django? - PullRequest
0 голосов
/ 29 января 2019

Я сейчас создаю небольшой проект с использованием Django, я заметил проблему, когда вошедший в систему пользователь получал доступ к странице других пользователей, просто меняя идентификатор в URL, т.е. Это URL текущего зарегистрированногоу пользователя

http://localhost:8000/home/myBooks/7/

, изменив этот идентификатор с 7 на 6
т.е.

 http://localhost:8000/home/myBooks/6/

Он получал доступ к этой странице, я использовал @login_required дляфункциональные представления и LoginRequiredMixin для представлений на основе классов, но они не помогают, что еще мне нужно сделать, чтобы предотвратить эту проблему?

Мое приложение / views.py:

from django.shortcuts import render,redirect
from django.http import HttpResponse
from django.views.generic.edit import FormView
from . forms import BookForm
from django.contrib.auth.models import User
from . models import UserBooks
from django.contrib.auth.models import User
from django.views import generic
from django.contrib.auth.decorators import login_required
from .models import UserBooks
from django.shortcuts import get_object_or_404
from django.contrib.auth.mixins import LoginRequiredMixin
@login_required
def HomeView(request):
    return render(request,'home/homepage.html')
class BookDetailsView (LoginRequiredMixin,generic.DetailView):
    model=UserBooks
    template_name='home/bookdetails.html'
class BooksView (LoginRequiredMixin,generic.DetailView):
     model=User
     template_name='home/mybooks.html'

@login_required
def addBooks(request):
    if (request.method=='POST'):
        form=BookForm(data=request.POST)
        if(form.is_valid()):
            u=UserBooks()
            u.book_name=form.cleaned_data['book_name']
            u.book_author=form.cleaned_data['book_author']
            u.book_ISBN=form.cleaned_data['book_ISBN']
            u.book_status=True
            u.book_genre=form.cleaned_data['book_genre']
            u.username=request.user.username
            u.user_id = User.objects.get(username=request.user.username)
            u.save()
            return redirect('/')
    else:
        form = BookForm()
    return render (request,'home/addbooks.html',{'form':form})

мои приложения / models.py:

from django.db import models
from django.contrib.auth.models import User
class UserBooks(models.Model):
    user_id = models.ForeignKey(User,on_delete=models.CASCADE,null=True)
    username = models.CharField(max_length=200)
    book_name = models.CharField(max_length=200)
    book_author = models.CharField(max_length=200)
    book_ISBN=models.CharField(max_length=200)
    book_genre = models.CharField(max_length=200)
    book_status=models.BooleanField(default=False)
    class Meta:
        unique_together = (("username", "book_ISBN"),)
    def __str__(self):
        return self.book_name

мои приложения / urls.py:

from django.urls import path
from . import views
app_name='home'
urlpatterns=[
    path('',views.HomeView,name='home'),
    path('addBooks/',views.addBooks,name='addBooks'),
    path('myBooks/<int:pk>/',views.BooksView.as_view(),name='myBooks'),
    path('<int:pk>/', views.BookDetailsView.as_view(), name='myBooks'),
    ]

Ответы [ 3 ]

0 голосов
/ 29 января 2019

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

Как вы написали, можно просто изменить URL-адрес и получить некоторые личные данные.

Другие проблемы могут быть:

  1. Количество пользователей в базе данных может быть легко подсчитано с помощью итераций по вашим URL.
  2. Пользователь может быть легко обнаружен по его идентификатору.Зная это, можно легко получить некоторые личные данные.
  3. Если вы решите изменить идентификаторы в своей базе данных, тогда все внешние ссылки будут повреждены ... и т. Д.

Учитывая, что я предлагаю подход, в котором вы используете идентификаторы внутри страны.Для внешнего использования (URL, ссылки) вы можете использовать uuids.

Для этого вам просто нужно дополнительное поле в вашей модели:

import uuid

uuid = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)

А вот пример URL:

url(r'^myBooks/(?P<user_uuid>\b[0-9A-Fa-f]{8}\b(-\b[0-9A-Fa-f]{4}\b){3}-\b[0-9A-Fa-f]{12}\b)/$',

После переключения на uuids будет практически невозможно "взломать" URL.

0 голосов
/ 29 января 2019
class BooksView(LoginRequiredMixin, DetailView):
    ...

    def get(self, request, *args, **kwargs):
        current_user = User.objects.get(id=self.request.user.pk)
        if current_user.pk == kwargs['pk']:
            return HttpResponseRedirect('/')
        else:
            return HttpResponseRedirect('profile-url')

Здесь я предполагаю, что если вы вошли в систему как пользователь, и вы пытаетесь проверить другой профиль пользователя, указав идентификатор в URL.Поэтому я добавляю метод get, который будет проверять запрашиваемый URL-адрес для текущего пользователя (books/7/ равен 7 - это текущий идентификатор пользователя), если нет, то перенаправить, например, на URL-адрес, иначе перенаправить на другой URL-адрес.Вы можете получить некоторую идею.Это может вам не совсем помочь.

0 голосов
/ 29 января 2019

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

class BooksView(LoginRequiredMixin, generic.DetailView):
     model = User
     template_name ='home/mybooks.html'

     def get_object(self):
        return self.request.user

...

path('myBooks/',views.BooksView.as_view(),name='myBooks'),
...