Вот полностью воспроизводимый образ докера сервера REST API Laravel:
FROM php
RUN apt-get update
RUN apt-get install zip -y
COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer
RUN composer create-project laravel/laravel frontend
WORKDIR frontend
COPY web.php web.php
RUN mv web.php routes
EXPOSE 8000
CMD [ "php", "artisan", "serve", "--host", "0.0.0.0" ]
Единственное, что я отредактировал, это одну конечную точку (web.php):
<?php
use Illuminate\Support\Facades\Route;
Route::get('/', function () {
return csrf_token();
});
Route::post('/', function (Request $request) {
if ($request->hasFile('source' )) { return ">> GOOD ! <<"; }
if ($request->hasFile('input.json')) { return ">> GOOD ! <<"; }
$x = count($_FILES);
return "DD >> $x << DD";
});
Я создаю и запускаю образ докера следующим образом:
$ docker build --tag host.translator.php --file Dockerfile .
$ docker run -p 8008:8000 -d -t --name translator.php host.translator.php
Тогда, как говорится в соответствующих постах (здесь , и здесь , , а также здесь):
$ Set-Variable -Name X -Value (curl.exe -X GET -F "[email protected]" http://127.0.0.1:8008/)
# X holds the token:
# echo $X
# U263lUv3dz9PH7ySm3GmgUUjHjjWm78cqofODUmh
Но когда я пытаюсь использовать этот токен, он не работает:
$ curl.exe --header "X-CSRFToken:$X" -X POST -F "[email protected]" http://127.0.0.1:8008/ | Select-String "<title>Page Expired"
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 6851 0 6609 100 242 80486 2947 --:--:-- --:--:-- --:--:-- 83548
<title>Page Expired</title>
Любая помощь очень ценится - спасибо!
Обновлено:
#
# used a new variable Z - just to be sure ...
#
$ Set-Variable -Name Z -Value (curl.exe -b cookiejar -X GET -F "[email protected]" http://127.0.0.1:8008/)
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 282 0 40 100 242 527 3194 --:--:-- --:--:-- --:--:-- 3760
$ echo $Z # this looks good, right ?
aHvU5WOaGs9qxOIzgdYb90TJUKPDgDaNhYjQNALW
#
$ type .\cookiejar # this looks ... hmmm ... good (I think ?)
# Netscape HTTP Cookie File
# https://curl.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.
#HttpOnly_127.0.0.1 FALSE / FALSE 1711103819 laravel_session eyJpdiI6IllsOW9KdlVzT1ZPcUJDOUdQRnUyZHc9PSIsInZhbHVlIjoiekpING13WFRaaDRLUHBUcVpNM0VjblBwVjlXM1VrSU1uYUF3dk43d0J6c0RvSDJ5UWZOU3lla1lKVjBNRnNVTXJOaTNMdmt3dlIvdW5HZDk1ODZUb0gxVWMySHh5cXBWeG5XbjVMQlpMQ2xoMzM0ODROQ1FGQ0NMQzFNaHNQMXMiLCJtYWMiOiI0MTg3ZTM0NTlmNWMzZGUyZDY3YzI2YWViYzc2MDZhMjAyMjA2NzE5YmRmYTRmYWRmYzQxODIzYmVlOThlZTkxIiwidGFnIjoiIn0%3D
#
# Now let's cross our fingers extra strong !
#
$ curl.exe -c cookiejar --header "X-CSRFToken:$Z" -X POST -F "[email protected]" http://127.0.0.1:8008/ | Select-String "<title>Pa
ge Expired"
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 6851 0 6609 100 242 85705 3138 --:--:-- --:--:-- --:--:-- 87833
242 83137 3044 --:--:- <title>Page Expired</title>- --
:--:-- --:--:-- 85637
если вы используете токены csrf, вам также необходимо использовать jar cookie, а также сохранять и повторно отправлять файлы cookie, поскольку токен csrf связан с сеансом пользователя, который передается с помощью файлов cookie.
@apokryfos, я думал, что единственной важной информацией в файле cookie является токен, не так ли?
@HansKilian вот оно :) {"name": "oren", "age": 6}
Токен CSRF хранится в сеансе пользователя, а затем проверяется на основании того, что получено от клиента, поэтому серверу необходимо убедиться, что токен действительно принадлежит пользователю, который сделал запрос (и пользователь определяется с помощью сеанса).
@apokryfos, ты имеешь в виду, что мне следует каким-то образом добавить дополнительную информацию в запрос POST? или я делаю это совершенно неправильно?
Попробуйте отправить запрос на получение, например curl.exe -b cookiejar -X GET -F "[email protected]" http://127.0.0.1:8008/ , и запрос на публикацию, например curl.exe -c cookiejar --header "X-CSRFToken:$X" -X POST -F "[email protected]" http://127.0.0.1:8008/, чтобы сохранить, а затем отправить файлы cookie.
@apokryfos, я отредактировал вопрос, чтобы показать ваше предложение - оно все равно не работает
@apokryfos Разве не следует поменять местами параметры -b и -c? Согласно справочной странице, -c хранит файлы cookie и -b отправляет их.
Пробовали ли вы выполнить запрос на публикацию в почтальоне, а затем проверить там код завитка?
@HansKilian, я попробовал это с переключенными флагами -b, -c, но это все равно не работает. Я не использую почтальон, но установлю его, если это поможет (?)
@Mr.Kenneth Я установил почтальона и отправил запрос GET (успешно) и запрос POST, который вернул Page Expired, как и раньше... какую настройку мне следует сделать в почтальоне?
хм... AFAIK, срок действия страницы - это ошибка 419, отсутствует токен csrf. Попробуйте следовать этому, как добавить токен в почтальоне. stackoverflow.com/a/49249850/13933721
просто сначала выполните простой запрос на публикацию без дополнительных параметров и простой ответ JSON, чтобы убедиться, что ваш запрос на публикацию успешен. затем проверьте функцию почтальона для завивки и попробуйте ее на своем bash.. если получилось, делайте свое дело






CSRF (подделка межсайтовых запросов) — это способ защитить сервер от подделки.
См. https://laravel.com/docs/11.x/csrf
Чтобы пройти эту проверку обычным способом, вам нужно передать заголовок X-CSRF-TOKEN (а не X-CSRFToken, как вы это сделали с опечаткой) и передать правильный токен CSRF.
Механизм токена CSRF следующий:
Итак, если вы отправляете запрос POST через CURL, то токен CSRF должен быть определен, правда, но вам нужно будет отправить самый новый.
Вы можете исключить URL-адреса из защиты CSRF, но будьте осторожны: по возможности не снижайте стандарты безопасности с помощью
->withMiddleware(function (Middleware $middleware) {
$middleware->validateCsrfTokens(except: [
'stripe/*',
'http://example.com/foo/bar',
'http://example.com/foo/*',
]);
})
и тогда запрос будет обработан должным образом. Если это точка входа (например, при публикации JWT для единого входа), то имеет смысл разрешить этой конкретной конечной точке работать без CSRF, поскольку она в любом случае аутентифицирует пользователя. В противном случае вам всегда придется получать последний токен CSRF и добавлять его в заголовок ваших запросов.
Оно работает !! Спасибо за подробный ответ! Я думаю, последнее, что я не до конца понял, это то, как содержимое файла cookiejar связано с последним токеном csrf - они оба меняют сам запрос, но это не один и тот же хэш (верно?), хэш cookiejar, кажется, много дольше
@OrenIshShalom рад помочь. Я предполагаю, что это разные хеши, но я это не проверял.
Думаю, чтобы его можно было полностью воспроизвести, нам также понадобится содержимое вашего
input.jsonфайла :)