Безопасна ли реализация добавления в корзину / удаления из корзины?
Я создаю сайт ecom и для того, чтобы реализовать функцию add_to_cart, я сделал следующее.
При нажатии на кнопку добавления в корзину вызывается функция javascript add_to_cart
, которую я написал:
<button type="button" onclick = "add_to_cart({{ product.pk }})">Add to Cart</button>
Это функция:
function add_to_cart(product_pk) {
let url = '/add-to-cart/' + product_pk.toString()
$.ajax({
type: 'GET',
url: url,
processData: false,
contentType: false
})
}
урлы для этого выглядят следующим образом:
path('add-to-cart/<str:product_pk>', views.add_to_cart, name='add_to_cart')
и, наконец, мой вид выглядит следующим образом:
def add_to_cart(request, product_pk):
cart = request.session['cart']
cart.append(product_pk)
request.session['cart'] = cart
context = {'length_of_cart': len(cart)}
return HttpResponse(content = dumps(context), content_type='application/json')
tldr: Нажмите кнопку, кнопка вызывает js, js делает get запрос к url, url запускает представление, логика в представлении добавляет товар в корзину.
Мне кажется, что это довольно "халтурно". Есть ли какие-либо проблемы безопасности, связанные с тем, что я здесь сделал?
Мне кажется, что это довольно "халтурно". Есть ли какие-либо проблемы безопасности, связанные с тем, что я здесь сделал?
Запрос GET не должен иметь побочные эффекты. Действительно, как сказано в спецификациях HTTP [w3.org]:
В частности, было установлено, что методы GET и HEAD НЕ ДОЛЖНЫ иметь значение выполнения какого-либо действия, кроме извлечения. Эти методы следует считать "безопасными".
Для выполнения запросов с побочными эффектами следует использовать POST, PUT, PATCH или DELETE.
Django будет автоматически пытаться проверить CSRF-токен, если вы делаете POST-запрос. Это делается для предотвращения уязвимости, которая может привести к появлению вредоносного JavaScript файла, использующего учетные данные вошедшего в систему пользователя для выполнения запросов. Django (стремится) предотвратить это с помощью маркера CSRF. Вы добавляете такой маркер в POST запрос, как объясняется в разделе AJAX документации :
function getCookie(name) {
let cookieValue = null;
if (document.cookie && document.cookie !== '') {
const cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
const cookie = cookies[i].trim();
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
const csrftoken = getCookie('csrftoken');
function add_to_cart(product_pk) {
let url = '/add-to-cart/' + product_pk.toString()
$.ajax({
type: 'POST',
url: url,
processData: false,
contentType: false,
headers: {'X-CSRFToken': csrftoken}
})
}
Наконец, мы должны создать представление, чтобы оно принимало только POST-запросы с помощью декоратора @require_POST
[Django-doc]:
from django.views.decorators.http import require_POST
@require_POST
def add_to_cart(request, product_pk):
# …