Laravel CSRF - 419 Срок действия страницы истек, после отправки запроса на другой веб-сайт - PullRequest
2 голосов
/ 19 марта 2020

В настоящее время я работаю на 2 сайтах. Один веб-сайт (веб-сайт A) представляет собой простую CMS, а другой веб-сайт (веб-сайт B) - это обычный веб-сайт для пользователей, где они могут управлять своими профилями и т. Д. c. Пользователь может просматривать пакеты в CMS. Эти пакеты получены с помощью запроса AJAX с другого сайта (веб-сайт B). эти пакеты также можно купить. Когда пользователь покупает пакет (веб-сайт A), на другой веб-сайт (веб-сайт B) отправляется запрос на публикацию.

Итак, чтобы уточнить, скажем, например, у нас есть веб-сайты A и B. Когда пользователь на веб-сайте А покупается посылка, отправляется почтовый запрос на «B.com/package/purchase». Есть только одна проблема с этим дизайном. В Laravel токен csrf должен отправляться с каждой формой. Поскольку я делаю POST-запрос к другому веб-сайту, я не могу сгенерировать токен CSRF с веб-сайта A, потому что тогда этот запрос всегда будет просрочен. Поэтому я должен использовать токен CSRF с веб-сайта B. Я пытался это сделать, но запрос все еще возвращает ошибку 419 Page Expired. Как я могу решить эту проблему?

Форма на веб-сайте A: (Эта форма находится внутри javascript добавления, таким образом, кавычки.

'<form method="POST" action="https://rainierlaansite.test/package/' + el.token +'/purchase" id="purchase-form">' +
    '<input type="hidden" value="'+ el.token +'" name="package_token">' +
    '<input name="_token" type="hidden" id="csrf-token" value=' + data[1] + '>' +
      '<h4>' +
        '<a href="#" id="download_package" class="badge badge-pill '+ (el.price == 0 ? 'badge-primary': 'badge-light') +'" onclick="document.getElementById(\'purchase-form\').submit();">' +
            (el.price == 0 ? 'Download': '$ ' + el.price) +
        '</a>' +
      '</h4>' +
'<form>' +

Запрос AJAX на веб-сайте A:

<script>
        $.ajax({
            headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content'), 'X-Requested-With': 'XMLHttpRequest'},
            url: 'https://www.rainierlaansite.test/api/packages/get',
            type: 'GET',
            data: {},
            success: function(data) {
                $('#package-loading').fadeOut();
                let wrapper = $("#packages-wrapper");
                let popup_list = $('.popup-list');
                let popup = 'popup-id';

                if(data == null) {
                    console.log('lol')
                }
                $.each(data[0], function(index, value) {
                    let el = data[0][index];
                    wrapper.append(
                        '<div class="row my-4" data-id='+ el.id +'>' +
                            '<div class="col-2 d-flex justify-content-center"><i class="fad fa-archive fa-2x"></i></div>' +
                            '<div class="col-6">' +
                                '<a href="#" class="popup" data-popup-id="'+ el.id +'"><h6 class="m-0">'+ el.name +'</h6></a>' +
                                '<p class="m-0 sub-text">'+ el.description +'</p>' +
                            '</div>' +
                            '<div class="col-4 d-flex justify-content-end align-items-center">' +
                                '<a href="#" id="download_package" class="badge badge-pill badge-light popup '+ (el.price == 0 ? 'badge-primary': 'badge-light') +'" style="font-size: 14px;" data-popup-id="'+ el.id +'">' + (el.price == 0 ? 'Download': '$ ' + el.price) +'</a>' +
                            '</div>' +
                        '</div>' + '<hr>'
                    );
                    popup_list.append(
                        '<div class="package-popup shadow popup-'+ el.id +'">' +
                            '<div class="package-popup-dialog animated zoomIn show faster">' +
                                '<div class="package-popup-content">' +
                                    '<div class="row">' +
                                        '<div class="col-2">' +
                                            '<div class="row">' +
                                                '<div class="col-12 d-flex justify-content-center">' +
                                                    '<i class="fad fa-archive fa-3x"></i>' +
                                                '</div>' +
                                            '</div>' +
                                        '</div>' +
                                        '<div class="col-7">' +
                                            '<div class="row">' +
                                                '<div class="col-12">' +
                                                    '<h4 class="m-0">' + el.name + '</h4>' +
                                                    '<p class="sub-text">' + el.creator + '</p>' +
                                                '</div>' +
                                            '</div>' +
                                        '</div>' +
                                        '<div class="col-3 text-center">' +
                                            '<form method="POST" action="https://rainierlaansite.test/package/' + el.token +'/purchase" id="purchase-form">' +
                                                '<input type="hidden" value="'+ el.token +'" name="package_token">' +
                                                '<input name="_token" type="hidden" id="csrf-token" value=' + data[1] + '>' +
                                                '<h4>' +
                                                    '<a href="#" id="download_package" class="badge badge-pill '+ (el.price == 0 ? 'badge-primary': 'badge-light') +'" onclick="document.getElementById(\'purchase-form\').submit();">' +
                                                    (el.price == 0 ? 'Download': '$ ' + el.price) +
                                                    '</a>' +
                                                '</h4>' +
                                            '<form>' +
                                        '</div>' +
                                        '<div class="offset-2 col-7">' +
                                            '<div class="rating">' +
                                                '<span><i class="fas fa-star yellow"></i></span>' +
                                                '<span><i class="fas fa-star yellow"></i></span>' +
                                                '<span><i class="fas fa-star yellow"></i></span>' +
                                                '<span><i class="fas fa-star yellow"></i></span>' +
                                                '<span><i class="fas fa-star grey"></i></span>' +
                                                '<small><a href="">· Uit 300 beoordelingen</a></small>' +
                                            '</div>' +
                                            '<small>Nog geen beoordelingen</small>' +
                                        '</div>' +
                                        '<div class="col-3 text-center">'+
                                            '<i class="far fa-download"></i> ' + el.downloads +
                                        '</div>' +
                                    '</div>' +
                                    '<div class="row my-5">' +
                                        '<div class="col-12">' +
                                            '<nav>' +
                                                '<div class="nav nav-tabs" id="nav-tab" role="tablist">' +
                                                    '<a class="nav-item nav-link active" id="nav-home-tab" data-toggle="tab" href="#nav-home" role="tab" aria-controls="nav-home" aria-selected="true">Details</a>' +
                                                    '<a class="nav-item nav-link" id="nav-profile-tab" data-toggle="tab" href="#nav-profile" role="tab" aria-controls="nav-profile" aria-selected="false">Reviews</a>' +
                                                    '<a class="nav-item nav-link" id="nav-contact-tab" data-toggle="tab" href="#nav-contact" role="tab" aria-controls="nav-contact" aria-selected="false">Version history</a>' +
                                                '</div>' +
                                            '</nav>' +
                                            '<div class="tab-content" id="nav-tabContent">' +
                                                '<div class="tab-pane fade show active py-4" id="nav-home" role="tabpanel" aria-labelledby="nav-home-tab">' +
                                                    '<p>' + el.description + '</p>' +
                                                '</div>' +
                                                '<div class="tab-pane fade py-4" id="nav-profile" role="tabpanel" aria-labelledby="nav-profile-tab">' +
                                                    'Dit is twee tekst' +
                                                '</div>' +
                                                '<div class="tab-pane fade py-4" id="nav-contact" role="tabpanel" aria-labelledby="nav-contact-tab">' +
                                                    'Dit is tekst 3' +
                                                '</div>' +
                                            '</div>' +
                                        '</div>' +
                                    '</div>' +
                                '</div>' +
                            '</div>' +
                        '</div>'
                    );
                });

                $('.popup').on('click', function () {
                    if($(this).data(popup)) {
                        let item = $('.popup-' + $(this).data(popup));
                        item.addClass('show');
                        $(item).on('click', function(event) {
                            if (event.target.classList.contains("shadow")) {
                                item.removeClass('show');
                            }
                        })
                    }
                });
            },
            error: function(e) {
                $('#package-error').fadeIn().text("Unfortunately there was an error retrieving the packages");
            }
        });
    </script>

Что получает AJAX запрос

 public function get()
    {
        $csrf = json_encode(csrf_token());
        return response()
            ->json([Package::all(),  $csrf]);
    }

1 Ответ

1 голос
/ 19 марта 2020

Laravel позволяет легко защитить ваше приложение от атак подделки межсайтовых запросов (CSRF). Подделки межсайтовых запросов - это тип вредоносного эксплойта, при котором несанкционированные команды выполняются от имени аутентифицированного пользователя.

Laravel автоматически генерирует «токен» CSRF для каждого активного сеанса пользователя, управляемого приложением. Этот токен используется для проверки того, что аутентифицированный пользователь действительно выполняет запросы к приложению.

По умолчанию laravel предотвращает межсайтовые запросы с использованием токена CSRF. Если вы хотите, вы можете избежать проверки CSRF, добавив URI к массиву кроме в VerifyCsrfToken Middleware.

Установите VerifyCsrfToken Middleware в вашем App \ Http \ Middleware приложения https://www.rainierlaansite.test следующим образом

<?php

namespace App\Http\Middleware;

use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;

class VerifyCsrfToken extends Middleware
{
    /**
     * The URIs that should be excluded from CSRF verification.
     *
     * @var array
     */
    protected $except = [
        'api/packages/get',
    ];
}
...