Bir anonim kullanıcı 403 hatası sonrasında giriş formuna nasıl yeniden yönlendirilir?


13

Bu tür bir kullanıcı 403 hatasıyla karşılaşırsa, anonim bir kullanıcıyı giriş formuna yeniden yönlendirmek istiyorum.

Olay abonesi oluşturdum ve bu benim kodum, ancak geçerli sayfada döngü sonunda.

/**
   * Redirect anonymous user to login page if he encounters 404 or 403
   * response.
   *
   * @param \Symfony\Component\HttpKernel\Event\GetResponseEvent $response
   *   The created response object that will be returned.
   * @param string $event
   *   The string representation of the event.
   * @param \Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher $event_dispatcher
   *   Event dispatcher that lazily loads listeners and subscribers from the dependency injection
   *   container.
   */
  public function checkLoginNeeded(GetResponseEvent $response, $event, ContainerAwareEventDispatcher $event_dispatcher) {
    $routeMatch = RouteMatch::createFromRequest($response->getRequest());
    $route_name = $routeMatch->getRouteName();
    $is_anonymous = \Drupal::currentUser()->isAnonymous();
    $is_not_login = $route_name != 'user.login';

    if ($is_anonymous && $route_name == 'system.403' && $is_not_login) {
      $query = $response->getRequest()->query->all();
//      $query['destination'] = $routeMatch->getRouteObject()->getPath();
      $query['destination'] = \Drupal::url('<current>');
      $login_uri = \Drupal::url('user.login', [], ['query' => $query]);
      $returnResponse = new RedirectResponse($login_uri, Response::HTTP_FOUND);
      $response->setResponse($returnResponse);
    }
  }

Bunun cevabın zaten hedef (mevcut uri) ve system.404 ve system.403 içerdiği gerçeğiyle ilgili olduğunu düşünüyorum, bunu geçersiz kılmamı engelleyen bazı yüksek önceliğe sahip.


Yalnızca yöntem yerine sınıfınızın tamamını ekleyebilir misiniz?
googletorp

Yalnızca $ olayı vardır [KernelEvents :: REQUEST] = 'checkLoginNeeded'; getSubscribedEvents () yönteminde.

Yanıtlar:


14

Bu sorunun programlı olarak nasıl yapılacağı hiç cevaplanmadığını gördüm. Bir İstisna Abonesine yerleştirildiğinde kod aslında çalışır:

/src/EventSubscriber/RedirectOn403Subscriber.php:

<?php

namespace Drupal\mymodule\EventSubscriber;

use Drupal\Core\EventSubscriber\HttpExceptionSubscriberBase;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Url;

class RedirectOn403Subscriber extends HttpExceptionSubscriberBase {

  protected $currentUser;

  public function __construct(AccountInterface $current_user) {
    $this->currentUser = $current_user;
  }

  protected function getHandledFormats() {
    return ['html'];
  }

  public function on403(GetResponseForExceptionEvent $event) {
    $request = $event->getRequest();
    $is_anonymous = $this->currentUser->isAnonymous();
    $route_name = $request->attributes->get('_route');
    $is_not_login = $route_name != 'user.login';
    if ($is_anonymous && $is_not_login) {
      $query = $request->query->all();
      $query['destination'] = Url::fromRoute('<current>')->toString();
      $login_uri = Url::fromRoute('user.login', [], ['query' => $query])->toString();
      $returnResponse = new RedirectResponse($login_uri);
      $event->setResponse($returnResponse);
    }
  }

}

mymodule.services.yml:

services:
  mymodule.exception403.subscriber:
    class: Drupal\mymodule\EventSubscriber\RedirectOn403Subscriber
    tags:
      - { name: event_subscriber }
    arguments: ['@current_user']

4
Bu çalışır ve muhtemelen ilgili modüller (Kurallar dahil) kararlı sürümlere sahip olana kadar en iyi cevaptır. $ Sorgulamak için -> toString () eklemek zorundayım ['destination'] = Url :: fromRoute ('<current>') bu işe almak için
Colin Shipton

2
Bu cevap daha yüksek görünmeyi hak ediyor!
pbonnefoi

13

En kolay yol, aşağıdakileri içeren /admin/config/system/site-informationalana göz atmak ve doldurmaktırDefault 403 (access denied) pageuser/login


7
Bu iyi bir çözümdür, ancak açıklamasında bahsettiğim kullanıcının zaten giriş yapmış olabileceği gerçeğini dikkate almaz.

9

Sadece bu sorunun başlığına bakarak (= Kullanıcı 403'ten giriş formuna nasıl yönlendirilir? ), Aşağıda açıklandığı gibi herhangi bir özel kod olmadan 2 seçenek vardır.

Seçenek 1: CustomError modülünü kullanma

CustomError modülü site yöneticisi HTTP için özel hata sayfaları oluşturmak için olanak sağlar durum 403 (erişim engellendi) kodları ve 404 (bulunamadı), bunların her biri için düğümleri yaratmadan. Özellikleri hakkında daha fazla ayrıntı (proje sayfasından):

  • Yapılandırılabilir sayfa başlığı ve açıklamaları.
  • Normal düğümlerde olduğu gibi yazar ve tarih / saat başlıkları yoktur.
  • HTML biçimli metinler sayfa gövdesine yerleştirilebilir.
  • Hata sayfaları düzenlenebilir.
  • Giriş yapmamış ve giriş gerektiren bir alana erişmeye çalışan kullanıcılar giriş yaptıktan sonra erişmeye çalıştıkları sayfaya yönlendirilecektir.
  • 404'ler için özel yönlendirmelere izin verir.

Muhtemelen " Oturum açmamış kullanıcılar ve giriş gerektiren bir alana erişmeye çalışan kullanıcılar giriş yaptıktan sonra erişmeye çalıştıkları sayfaya yönlendirilecekler " bölümü ile ilgileneceksiniz .

D8 için bu modülün 8.x-1.x-dev sürümü de mevcut, bu konuda daha fazla ayrıntı Sayı # 2219227'de bulunabilir .

2. Seçenek: Kurallar modülünü kullanma

"Varsayılan 403" sayfasının yolunun no_access(admin aracılığıyla) ayarlandığını varsayın . Ardından, Kurallar modülünü kullanarak Olay olarak "Düğümü ziyaret ettikten sonra" gibi bir kural içeren bir kural oluşturun no_access. Böylece tüm kural şöyle görünecektir:

  • Olaylar: Düğümü ziyaret ettikten sonrano_access
  • Koşullar:

    1. Kullanıcının rolleri -Parameter: User: [site:current-user], Roles: anonymous user
    2. NOT Metin karşılaştırması -Parameter: Text: [site:current-page:url], Matching text: user/login
  • Eylemler: Sayfa yönlendirmesi -Parameter: URL: user/login

Bunu yapmak isterseniz , Drupal mesaj alanında "Giriş için gerekli olan bir sayfayı ziyaret etmeye çalıştınız ..." gibi bir şeyle bazı (bilgilendirici) mesajlar görüntülemek için başka bir Eylem bile ekleyebilirsiniz .

Doğru, ekstra katkıda bulunan bir modülü ( Kurallar ) etkinleştirmenizi gerektirebilir . Ancak, artan popülaritesiyle de belirtildiği gibi, bu modül muhtemelen herhangi bir sitede ( Görünümler modülüne benzer) zaten etkinleştirilmiştir , çünkü bu modül için düzinelerce kullanım durumu vardır.

D8 için bu modül için 8.x-3.x-alfa1 sürümü de mevcut, D8 sürümü hakkında daha fazla ayrıntı , Kurallar " Kural 8.x Yol Haritası " bağlantısını içeren Sayı # 2574691'de bulunabilir.

Yukarıdakiler yardımcı olmazsa, döngünüzün nedeninin (veya sorunuzdaki gibi "bazı yüksek öncelikli") " Nasıl belirlenir " sorusuna benzer bir şeyle engellenip önlenemeyeceğini / açıklayamayacağını kontrol etmek isteyebilirsiniz "İçerik" görüntülenecek "? " gibi bir Kural etkinliği .


4

Sanırım sorunun çözümü basit. Kolayca özel bir sayfa oluşturabilir 404ve 403bu sayfanın içinde anonim kullanıcıları sayfaya yönlendirebilirsiniz /user.

Bu kodu kullanabilirsiniz

function YOURTHEME_preprocess_page(&$vars) {
   $header = drupal_get_http_header('status'); 
   if ($header == '404 Not Found') {     
       $vars['theme_hook_suggestions'][] = 'page__404';
   }
}

Ne zaman 404 meydana gelirse page--404.tpl.phpkullanılacaktır. Bu sayfada bu kodu kullanın

if(user_is_logged_in() == false){
       /// You can do anything here.
}

Nasıl özel 403 ve Drupal 404 sayfa yapmak için bir sayfa oluşturma başka bir yöntemi açıklar 403ve 404.


5
Hey dostum, etiketleri ve kodu kontrol etmelisin. Bu adam açıkça Drupal 8 kullanıyor.
alexej_d

1
merhaba, ona algoritma verdim, kolayca 8biçimlendirmek için değiştirebilirsiniz
M ama D

3

Bunu yapmanın en kolay yolu, Redirect 403 to User Login modülünü kullanmaktır (D8 için geliştirici sürümü mevcuttur). İşte onunla ilgili bir alıntı (proje sayfasından):

HTTP 403 hata sayfasını Drupal / kullanıcı / oturum açma sayfasına, aşağıdakileri okuyan isteğe bağlı bir mesajla yönlendirin:

"Erişim reddedildi! Bu sayfayı görebilmek için giriş yapmalısınız."

Ayrıca, istenen sayfa url sorgu dizesine eklenir, böylece giriş başarılı olduktan sonra, kullanıcı doğrudan başlangıçta gitmeye çalıştıkları yere alınır.


1
Bu cevap neden reddedildi?
Miloš Kroulík

@ milos.kroulik Sanırım soru Drupal 8 hakkında ama bu modül için 7ve6
M ama D

1
Hayır, bu modülün geliştirme aşamasında Drupal 8 versiyonu yok
Colin Shipton

1
Kesin oy, cevabın "sadece bağlantı" cevabı (cevapların düşürülmesinin veya silinmesinin tipik bir nedeni ...) olduğundan emindi. Bu tür cevaplar genellikle "düşük quaity cevaplar" inceleme kuyruğunda da görünür ... Daha gelişmiş bir sürüm için bu cevabın düzenlenmiş sürümüne bakın (artık yalnızca bağlantı yanıtı olarak görülme riski yoktur).
Pierre.Vriens

Kullanıcı zaten giriş yaptıysa veya site hızlı404 ve 403 kullanıyorsa bu cevap dikkate alınmaz.

0

(1) "/my403.html" gibi bir takma adla sayfa düğümü oluşturma

(2) / admin / config / system / site-information adresine gidin ve "/my403.html" dosyasını 403-Hata sayfası olarak ayarlayın

(3) / admin / structure / block dizinine gidin ve "Kullanıcı girişi" bloğunu (Bölüm Formları) ana içerik bölgesine ekleyin. Bloğun görünümünü "my403.html" ve "konuk" rolüyle sınırlandırın.

Bu kadar.

Daha fazla kontrole ihtiyacınız varsa, 403 sayfanız için bir denetleyici oluşturun ve UserLoginForm'u elle ekleyin.

Saygılarımla, Rainer

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.