Рейтинг:5

В хуке, как я могу отличить веб-пользователей от пользователей JSON:API?

флаг cn

У меня есть веб-сайт Drupal, на котором также размещено приложение Ionic через JSON: API. Я хочу, чтобы пользователи веб-сайта перенаправлялись на вставку объекта, поэтому я добавил такое перенаправление:

функция MYMODULE_flagging_insert (FlaggingInterface $flagging) {
  $redirect_url = Url::fromRoute(MYCLASS::SECRET_ROUTE)->toString();
  $response = новый RedirectResponse($url);
  $ответ->отправить();
}

Этот код будет перенаправлять веб-пользователей, как и ожидалось, когда они добавят флаг. Однако этот код нарушает работу приложения JSON:API. Когда я добавляю флаг с пользователем из JSON: API, я получаю эту ошибку:

    RuntimeException: не удалось запустить сеанс, поскольку заголовки уже были отправлены "/app/vendor/symfony/http-foundation/Response.php" в строке 384.в Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage->start() (строка 152 файла /app/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php)
#0 /app/web/core/lib/Drupal/Core/Session/SessionManager.php(162): Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage->start()
#1 /app/web/core/lib/Drupal/Core/Session/SessionManager.php(193): Drupal\Core\Session\SessionManager->startNow()
#2 /app/vendor/symfony/http-foundation/Session/Session.php(189): Drupal\Core\Session\SessionManager->save()
#3 /app/web/core/lib/Drupal/Core/StackMiddleware/Session.php(60): Symfony\Component\HttpFoundation\Session\Session->save()
#4 /app/web/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(47): Drupal\Core\StackMiddleware\Session->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#5 /app/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(106): Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#6 /app/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(85): Drupal\page_cache\StackMiddleware\PageCache->pass(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#7 /app/vendor/asm89/stack-cors/src/Asm89/Stack/Cors.php(60): Drupal\page_cache\StackMiddleware\PageCache->handle(Object(Symfony\Component\HttpFoundation\Request), 1, истинный)
#8 /app/web/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(47): Asm89\Stack\Cors->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#9 /app/web/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(52): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#10 /app/vendor/stack/builder/src/Stack/StackedHttpKernel.php(23): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#11 /app/web/core/lib/Drupal/Core/DrupalKernel.php(716): Stack\StackedHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#12 /app/web/index.php(19): Drupal\Core\DrupalKernel->handle(Object(Symfony\Component\HttpFoundation\Request))
# 13 {основной}

Итак, есть ли способ определить в ловушке вставки (или других ловушках), вошел ли пользователь в систему через веб-сайт Drupal или через JSON: API?

Я хочу добавить перенаправление, если пользователь получает доступ к Drupal через веб-сайт, но я не хочу использовать перенаправление, если пользователь получает доступ к Drupal через приложение.

No Sssweat avatar
флаг ua
Может быть, вы можете отличить, проверив, какой браузер они используют? См. [Как получить точное имя и версию браузера?] (https://stackoverflow.com/questions/8754080/how-to-get-exact-browser-name-and-version/8754134)
флаг cn
@NoSssweat Я использую инфраструктуру Ionic для своего приложения, которое отображает контент в веб-просмотре. Таким образом, строка браузера будет одинаковой для пользователей мобильных приложений и пользователей, заходящих на веб-сайт через свои мобильные устройства.
apaderno avatar
флаг us
`hook_entity_insert()` не подходит для перенаправления пользователей. Предполагается, что пользователи создают объект из пользовательского интерфейса, но это не всегда так, поскольку ловушка будет вызываться также при программном создании объекта. Аналогичная ошибка перенаправляет пользователей в `hook_entity_view()`, который также вызывается при запуске задач cron: это хук, используемый модулем поиска для индексации узлов.
Рейтинг:3
флаг cn

Использование редиректов с $ответ->отправить() как это работало:

  $response = новый RedirectResponse($url);
  $ответ->отправить();

Но это больше не работает в Drupal 9.2. Кроме того, он ломает JSON:API в версиях до 9.2. Как правильно это сделать, подробно описано в этот отличный ответ.

По сути, вам нужно создать свой собственный http_middleware для обработки редиректов. С http_middleware применяется только к http/веб-запросам, не мешает JSON:API, поэтому проблема решена.

4uk4 avatar
флаг cn
Этот подход может работать в этом конкретном запросе POST, но в обычном запросе Drupal GET я бы использовал кешируемый TrustedRedirectResponse как можно скорее. Например, если это зависит только от аутентифицированного пользователя в подписчике события запроса сразу после аутентификации. Или в подписчике исключения или ответа, если вам нужно подождать, пока не возникнет исключение или не будет построен ответ.

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.