I have a Drupal website that also hosts an Ionic app via JSON:API. I want website users to be redirected on entity insert, so I added a redirect like this:
function MYMODULE_flagging_insert(FlaggingInterface $flagging) {
$redirect_url = Url::fromRoute(MYCLASS::SECRET_ROUTE)->toString();
$response = new RedirectResponse($url);
$response->send();
}
This code will redirect web users as expected when they add a flag. However, this code breaks the JSON:API app. When I add a flag with a user from JSON:API, I get this error:
RuntimeException: Failed to start the session because headers have already been sent by "/app/vendor/symfony/http-foundation/Response.php" at line 384. in Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage->start() (line 152 of /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, true)
#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 {main}
So is there a way to detect in an insert hook (or other hooks) whether the user is logged in through the Drupal website or through JSON:API?
I want to add a redirect if the user is accessing Drupal through the website, but I don't want to use a redirect if the user is accessing Drupal through the app.
hook_entity_insert()
is the wrong hook to redirect users. It assumes the users are creating an entity from the UI, but that's not always the case, as the hook would be invoked also when the entity is programmatically created. Similar mistake is redirecting users inhook_entity_view()
, which is also invoked when cron tasks run: It's the hook used from the Search module to index nodes.