Puncte:5

Într-un cârlig, cum pot face distincția între utilizatorii web și utilizatorii JSON:API?

drapel cn

Am un site web Drupal care găzduiește și o aplicație Ionic prin JSON:API. Vreau ca utilizatorii site-ului web să fie redirecționați pe inserarea entității, așa că am adăugat o redirecționare ca aceasta:

funcția MYMODULE_flagging_insert(FlaggingInterface $flagging) {
  $redirect_url = Url::fromRoute(MYCLASS::SECRET_ROUTE)->toString();
  $răspuns = new RedirectResponse($url);
  $răspuns->trimite();
}

Acest cod va redirecționa utilizatorii web așa cum se aștepta atunci când adaugă un semnalizator. Cu toate acestea, acest cod rupe aplicația JSON:API. Când adaug un steag cu un utilizator din JSON:API, primesc această eroare:

    RuntimeException: Nu s-a pornit sesiunea deoarece anteturile au fost deja trimise de „/app/vendor/symfony/http-foundation/Response.php” la linia 384.în Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage->start() (linia 152 din /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, Adevărat)
#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(Obiect(Symfony\Component\HttpFoundation\Request))
#13 {principal}

Deci, există o modalitate de a detecta într-un cârlig de inserare (sau alte cârlige) dacă utilizatorul este conectat prin site-ul web Drupal sau prin JSON:API?

Vreau să adaug o redirecționare dacă utilizatorul accesează Drupal prin intermediul site-ului web, dar nu vreau să folosesc o redirecționare dacă utilizatorul accesează Drupal prin aplicație.

No Sssweat avatar
drapel ua
Poate puteți distinge verificând ce browser folosesc? Consultați [Cum să obțineți numele și versiunea exactă a browserului?](https://stackoverflow.com/questions/8754080/how-to-get-exact-browser-name-and-version/8754134)
drapel cn
@NoSssweat Folosesc cadrul Ionic pentru aplicația mea, care afișează conținut într-o vizualizare web. Deci șirul browserului va fi același pentru utilizatorii de aplicații mobile și utilizatorii care accesează site-ul web prin dispozitivele lor mobile.
apaderno avatar
drapel us
`hook_entity_insert()` este cârligul greșit pentru a redirecționa utilizatorii. Se presupune că utilizatorii creează o entitate din interfața de utilizare, dar acesta nu este întotdeauna cazul, deoarece cârligul ar fi invocat și atunci când entitatea este creată programatic. O greșeală similară este redirecționarea utilizatorilor în `hook_entity_view()`, care este, de asemenea, invocată atunci când se execută activități cron: este cârligul folosit din modulul Căutare pentru a indexa nodurile.
Puncte:3
drapel cn

Utilizarea redirecționărilor cu $răspuns->trimite() asa mergea asta:

  $răspuns = new RedirectResponse($url);
  $răspuns->trimite();

Dar, acest lucru nu mai funcționează în Drupal 9.2. De asemenea, rupe JSON:API în versiunile anterioare 9.2. Modul corect de a face acest lucru este descris în detaliu în acest răspuns excelent.

Practic, trebuie să-ți creezi propriul personalizat http_middleware pentru a gestiona redirecționările. De cand http_middleware se aplică numai solicitărilor http/web, nu interferează cu JSON:API, deci problema este rezolvată.

4uk4 avatar
drapel cn
Această abordare ar putea funcționa în această solicitare POST specifică, dar într-o solicitare normală Drupal GET aș folosi un TrustedRedirectResponse care poate fi stocat în cache cât mai curând posibil. De exemplu, dacă depinde doar de utilizatorul autentificat într-un abonat de eveniment de solicitare imediat după ce a avut loc autentificarea. Sau într-un abonat la un eveniment de excepție sau răspuns, dacă trebuie să așteptați până când se ridică o excepție sau se construiește un răspuns.

Postează un răspuns

Majoritatea oamenilor nu înțeleg că a pune multe întrebări deblochează învățarea și îmbunătățește legătura interpersonală. În studiile lui Alison, de exemplu, deși oamenii își puteau aminti cu exactitate câte întrebări au fost puse în conversațiile lor, ei nu au intuit legătura dintre întrebări și apreciere. În patru studii, în care participanții au fost implicați în conversații ei înșiși sau au citit transcrieri ale conversațiilor altora, oamenii au avut tendința să nu realizeze că întrebarea ar influența – sau ar fi influențat – nivelul de prietenie dintre conversatori.