如何通过简单地在django中更改url中的id来防止已登录用户访问其他用户的个人资料?

时间:2019-01-29 09:43:40

标签: django django-models django-forms django-views

我目前正在使用Django构建一个小型项目,我注意到一个问题,即通过简单地更改url中的id(即,已登录用户即可访问其他用户页面) 这是当前登录用户的网址

strictNullChecks

通过将该ID从7更改为6

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

他正在访问该页面,我已将 http://localhost:8000/home/myBooks/6/ 用于基于功能的视图,将@login_required用于基于类的视图,但是它们没有帮助,我还需要采取其他措施来防止此问题?

我的app / views.py:

LoginRequiredMixin

我的apps / models.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})

我的apps / urls.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

3 个答案:

答案 0 :(得分:1)

如果您的视图应始终显示当前用户的详细信息,则不要将ID放在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'),

答案 1 :(得分:0)

如果您刚开始开发应用程序,则可以在网址中使用pks。但是,当涉及到真正可运行的应用程序时,可能会导致一些安全问题。

正如您所写,您可以简单地更改url并获取一些私有数据。

其他问题可能是:

  1. 通过您的URL进行迭代可以很容易地计算出数据库中的用户数量。
  2. 通过其ID可以轻松检测到用户。知道这一点就可以轻松获取一些私人数据。
  3. 如果您决定更改数据库中的ID,则所有外部链接都将被破坏...等等。

考虑到这一点,我建议您在内部使用id的方法。对于外部使用(URL,链接),您可以使用uuid。

为此,您只需在模型中添加其他字段即可:

import uuid

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

这是示例网址:

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)/$'

切换到uuid后,几乎不可能“入侵” URL。

答案 2 :(得分:0)

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中提供ID来检查另一个用户配置文件。因此,我添加了一个get方法,该方法将检查请求的URL ID是否为当前用户(books/7/为7是当前用户ID),如果不是,则重定向到URL,例如,否则重定向到另一个URL。你会知道的。这可能无法完全帮助您。