假设我有一个在数据库中执行某项操作的表单,并且需要POST发送的用户身份验证,是否可以在请求某人恶意更改用户为了利用这个系统?
以下示例在数据库中创建项目,但需要登录用户。有人可以在 request.user 中发送其他用户的数据吗?
from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from items_core.models import Item
from items.forms import CreateItemForm
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
@login_required
def create(request):
errors = None
if request.method == 'POST':
form = CreateItemForm(request.POST)
if form.is_valid():
try:
Item.objects.get(
name = form.cleaned_data['name'],
user = request.user
)
errors = 'Item already exist. Please provide other name.'
except Item.DoesNotExist:
Item.objects.create(
name = form.cleaned_data['name'],
user = request.user
)
return redirect('items:list')
form = CreateItemForm()
else:
form = CreateItemForm()
template = {
'form':form,
'items':Item.objects.filter(user=request.user),
'request':request,
'errors':errors
}
return render(request, 'items/item_create.html', template)
谢谢!
答案 0 :(得分:4)
request.user
对象的类型为SimpleLazyObject
,由auth middleware
添加到请求对象。
SimpleLazyObject(LazyObject):
用于延迟包装类的实例化
在请求实际登录用户时,将调用get_user
方法。
def get_user(request):
if not hasattr(request, '_cached_user'):
request._cached_user = auth.get_user(request)
return request._cached_user
在这里,auth.get_user()
会以这种方式验证:
backend_path = request.session[BACKEND_SESSION_KEY]
backend = load_backend(backend_path)
user = backend.get_user(user_id) or AnonymousUser()
因此,如果request.user
对象被篡改,则此验证将失败,因为会话数据验证将失败
答案 1 :(得分:3)
user
上的 request
属性,request.user
由AuthenticationMiddleware
设置。 process_request
此中间件内部使用由get_user()
中定义的django auth系统提供的django.contrib.auth.__init__.py
。
此get_user()
使用django会话,django会话内部使用cookie。 Django会话使用key
为sessionid
的Cookie。
因此,如果恶意用户获取合法用户的cookie并将此cookie发送到服务器,服务器将认为该请求来自合法用户并将以合法用户身份登录。但由于该请求是由恶意用户发送的,因此他现在可以访问合法用户的资源。