วิธีการเปลี่ยนเส้นทางผู้ใช้ที่ไม่ระบุชื่อไปยังแบบฟอร์มการเข้าสู่ระบบหลังจากข้อผิดพลาด 403?


13

ฉันต้องการเปลี่ยนเส้นทางผู้ใช้ที่ไม่ระบุชื่อไปยังแบบฟอร์มการเข้าสู่ระบบหากผู้ใช้ดังกล่าวพบข้อผิดพลาด 403

ฉันได้สร้างผู้สมัครสมาชิกของเหตุการณ์และนี่คือรหัสของฉัน แต่ฉันจบลงด้วยการวนซ้ำในหน้าปัจจุบัน

/**
   * 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);
    }
  }

ฉันคิดว่าสิ่งนี้เกี่ยวข้องกับความจริงที่ว่าคำตอบนั้นมีปลายทาง (ปัจจุบัน uri) และ system.404 และ system.403 มีลำดับความสำคัญสูงที่ป้องกันไม่ให้ฉันแทนที่สิ่งนี้


คุณสามารถเพิ่มคลาสทั้งหมดของคุณแทนที่จะเป็นวิธีการได้หรือไม่
googletorp

มีเพียง $ events [KernelEvents :: REQUEST] = 'checkLoginNeeded'; ในวิธีการ getSubscribedEvents ()

คำตอบ:


14

ฉันเคยเห็นว่าคำถามนี้ไม่เคยตอบว่าจะทำอย่างไรกับการเขียนโปรแกรม รหัสใช้งานได้จริงเมื่ออยู่ใน Exception Subscriber:

/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
วิธีนี้ใช้ได้ผลและอาจเป็นคำตอบที่ดีที่สุดจนกว่าโมดูลที่เกี่ยวข้อง (รวมกฎ) จะมีการเผยแพร่ที่เสถียร ฉันต้องเพิ่ม -> toString () ไปที่ $ query ['ปลายทาง'] = Url :: fromRoute ('<current>') เพื่อให้มันใช้งานได้
Colin Shipton

2
คำตอบนี้สมควรที่จะปรากฏขึ้นที่สูงขึ้น!
pbonnefoi

13

วิธีที่ง่ายที่สุดคือการเรียกดู/admin/config/system/site-informationและกรอกข้อมูลในฟิลด์ที่อ่านDefault 403 (access denied) pageด้วยuser/login


7
นั่นเป็นทางออกที่ดี แต่ก็ไม่ได้คำนึงถึงความจริงที่ว่าผู้ใช้อาจเข้าสู่ระบบแล้วซึ่งฉันได้กล่าวถึงในคำอธิบาย

9

เพียงแค่ดูชื่อของคำถามนี้ (= จะเปลี่ยนเส้นทางผู้ใช้ไปยังแบบฟอร์มการเข้าสู่ระบบจาก 403 ได้อย่างไร ) มี 2 ตัวเลือกให้ทำโดยไม่ต้องมีรหัสที่กำหนดเองตามรายละเอียดด้านล่าง

ตัวเลือกที่ 1: ใช้โมดูล CustomError

CustomErrorโมดูลจะช่วยให้ผู้ดูแลระบบเว็บไซต์เพื่อสร้างหน้าข้อผิดพลาดที่กำหนดเองสำหรับรหัสสถานะ HTTP 403 (การเข้าถึงถูกปฏิเสธ) และ 404 (ไม่พบ) โดยไม่ต้องสร้างโหนดสำหรับแต่ละของพวกเขา รายละเอียดเพิ่มเติมเกี่ยวกับคุณสมบัติ (จากหน้าโครงการ):

  • ชื่อหน้าและคำอธิบายที่กำหนดค่าได้
  • ไม่มีผู้เขียนและส่วนหัววันที่ / เวลาเช่นเดียวกับโหนดปกติ
  • สามารถจัดรูปแบบข้อความ HTML ใด ๆ ในส่วนของหน้า
  • หน้าข้อผิดพลาดสามารถใช้ได้
  • ผู้ใช้ที่ไม่ได้เข้าสู่ระบบและพยายามเข้าถึงพื้นที่ที่ต้องการเข้าสู่ระบบจะถูกเปลี่ยนเส้นทางไปยังหน้าเว็บที่พวกเขาพยายามเข้าถึงหลังจากที่พวกเขาเข้าสู่ระบบ
  • อนุญาตการเปลี่ยนเส้นทางที่กำหนดเองสำหรับ 404s

คุณอาจสนใจส่วนใหญ่เกี่ยวกับ " ผู้ใช้ที่ไม่ได้เข้าสู่ระบบและพยายามเข้าถึงพื้นที่ที่ต้องมีการเข้าสู่ระบบจะถูกเปลี่ยนเส้นทางไปยังหน้าเว็บที่พวกเขาพยายามเข้าถึงหลังจากเข้าสู่ระบบ "

สำหรับ D8 มีรุ่น 8.x-1.x-devสำหรับโมดูลนี้พร้อมใช้งานนอกจากนี้ยังมีรายละเอียดเพิ่มเติมเกี่ยวกับเรื่องนี้สามารถพบได้ในรุ่น # 2219227

ตัวเลือก 2: ใช้โมดูลกฎ

สมมติว่าเส้นทางของหน้า "Default 403" ถูกตั้งค่าเป็นno_access(ผ่านผู้ดูแลระบบ) จากนั้นสร้างกฎโดยใช้โมดูลกฎพร้อมด้วยกิจกรรมบางอย่างเช่น "หลังจากเยี่ยมชมโหนดno_access" เพื่อให้กฎทั้งหมดมีลักษณะดังนี้:

  • กิจกรรม:หลังจากเยี่ยมชมโหนดno_access
  • เงื่อนไข:

    1. ผู้ใช้มีบทบาท -Parameter: User: [site:current-user], Roles: anonymous user
    2. ไม่เปรียบเทียบข้อความ -Parameter: Text: [site:current-page:url], Matching text: user/login
  • การกระทำ: การ เปลี่ยนเส้นทางหน้า -Parameter: URL: user/login

หากคุณต้องการทำเช่นนั้นคุณสามารถเพิ่มแอคชั่นอื่นเพื่อแสดงข้อความ (ข้อมูล) บางส่วนในพื้นที่ข้อความ Drupal ด้วยบางอย่างเช่น "คุณพยายามเยี่ยมชมหน้าเว็บที่ต้องมีการลงชื่อเข้าใช้ ... "

จริงอยู่คุณอาจต้องเปิดใช้งานโมดูลที่สนับสนุนพิเศษ ( กฎ ) แต่ตามที่ระบุโดยความนิยมที่เพิ่มขึ้นเช่นกันโมดูลนั้นอาจเปิดใช้งานแล้วในเว็บไซต์ส่วนใหญ่ (คล้ายกับโมดูลViews ) เนื่องจากมีกรณีการใช้งานหลายสิบรายการสำหรับโมดูลนี้

สำหรับ D8 นั้นมีรุ่น8.x-3.x-alfa1สำหรับโมดูลนี้เช่นกันรายละเอียดเพิ่มเติมเกี่ยวกับรุ่น D8 สามารถพบได้ในฉบับที่ 2574691ซึ่งมีลิงก์ไปยังปัญหากฎ " กฎ 8.x แผนการทำงาน "

หากสิ่งที่กล่าวมาข้างต้นไม่สามารถช่วยได้คุณอาจต้องการตรวจสอบสาเหตุของการวนซ้ำ (หรือ "บางลำดับความสำคัญสูง" ในคำถามของคุณ) ไม่สามารถป้องกัน / อธิบายโดยสิ่งที่คล้ายกับคำตอบของคำถาม " วิธีการระบุ กิจกรรมกฎเช่น "เนื้อหากำลังจะ" ถูกดู "หรือไม่ "


4

ฉันเดาวิธีแก้ปัญหาของคุณง่าย ๆ คุณสามารถสร้างหน้าเว็บที่กำหนดเองสำหรับ404และ403จากนั้นภายในหน้านี้เปลี่ยนเส้นทางผู้ใช้ที่ไม่ระบุชื่อไปยัง/userหน้า

คุณสามารถใช้รหัสนี้

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

เมื่อใดก็ตามที่ 404 เกิดขึ้นคุณpage--404.tpl.phpจะถูกนำไปใช้ ในหน้านี้ใช้รหัสนี้

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

วิธีการทำที่กำหนดเอง 403 และ 404 หน้า Drupalอธิบายวิธีการสร้างหน้าอีกและ403404


5
สวัสดีเพื่อนคุณควรตรวจสอบแท็กและรหัส ผู้ชายคนนี้ใช้ Drupal 8 อย่างชัดเจน
alexej_d

1
สวัสดีฉันให้อัลกอริทึมแก่เขาเขาสามารถเปลี่ยนเป็น8รูปแบบได้อย่างง่ายดาย
M ama D

3

วิธีที่ง่ายที่สุดในการทำเช่นนั้นคือใช้โมดูลRedirect 403 ไปยัง User Login (มีรุ่น dev อยู่สำหรับ D8) นี่คือคำพูดเกี่ยวกับมัน (จากหน้าโครงการ):

เปลี่ยนเส้นทางหน้าข้อผิดพลาด HTTP 403 ไปยังหน้า Drupal / user / login ด้วยข้อความเพิ่มเติมที่อ่านได้:

"การเข้าถึงถูกปฏิเสธคุณต้องเข้าสู่ระบบเพื่อดูหน้านี้"

นอกจากนี้เพจที่ต้องการจะถูกผนวกเข้ากับสตริงการสืบค้น url เพื่อที่ว่าเมื่อเข้าสู่ระบบสำเร็จผู้ใช้จะเข้าสู่ที่ที่พวกเขาพยายามจะไป


1
ทำไมคำตอบนี้จึงลดลง?
MilošKroulík

@ milos.kroulik ฉันเดาเพราะคำถามเกี่ยวกับ Drupal 8 แต่โมดูลนั้นมีไว้สำหรับ7และ6
M ama D

1
ไม่มีโมดูลนั้นมี Drupal 8 รุ่นที่กำลังพัฒนา
Colin Shipton

1
ค่อนข้างแน่ใจว่า downvote นั้นเป็นเพราะคำตอบคือคำตอบ "ลิงก์อย่างเดียว" (เหตุผลทั่วไปสำหรับคำตอบที่ถูกลดระดับลงหรือลบไปแล้ว ... ) โดยทั่วไปคำตอบดังกล่าวจะปรากฏในคิวการตรวจสอบ "คำตอบที่มีคุณภาพต่ำ" ... โปรดอ้างถึงเวอร์ชันที่แก้ไขของคำตอบนี้เพื่อรับการปรับปรุงให้ดีขึ้น (ไม่เสี่ยงต่อการถูกพิจารณาว่าเป็นคำตอบสำหรับลิงก์เท่านั้น)
Pierre.Vriens

คำตอบนี้ไม่นำมาพิจารณาหากผู้ใช้เข้าสู่ระบบอยู่แล้วหรือหากเว็บไซต์นั้นใช้ fast404 และ 403

0

(1) สร้างโหนดหน้าด้วยนามแฝงเช่น "/my403.html"

(2) ไปที่ / admin / config / system / site-data และตั้งค่า "/my403.html" เป็น 403- หน้าข้อผิดพลาด

(3) ไปที่ / admin / structure / block และเพิ่มบล็อก "User login" (Sec. Forms) ไปยังพื้นที่เนื้อหาหลัก จำกัด ลักษณะที่ปรากฏของบล็อกไว้ที่หน้า "my403.html" และบทบาท "guest"

แค่นั้นแหละ.

หากคุณต้องการการควบคุมเพิ่มเติมให้สร้างตัวควบคุมสำหรับหน้า 403 ของคุณและเพิ่ม UserLoginForm ด้วยตนเอง

ขอแสดงความนับถือเรนเนอร์

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.