Làm cách nào để chuyển hướng người dùng ẩn danh đến biểu mẫu đăng nhập sau lỗi 403?


13

Tôi muốn chuyển hướng người dùng ẩn danh đến biểu mẫu đăng nhập nếu người dùng đó gặp lỗi 403.

Tôi đã tạo thuê bao sự kiện và đây là mã của tôi, nhưng tôi kết thúc vòng lặp trên trang hiện tại.

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

Tôi nghĩ rằng điều này có liên quan đến thực tế là phản hồi đã chứa đích (uri hiện tại) và system.404 và system.403 có một số ưu tiên cao ngăn cản tôi ghi đè lên điều này.


Bạn có thể thêm toàn bộ lớp của bạn thay vì chỉ phương thức?
googletorp

Chỉ có $ event [KernelEvents :: REQUEST] = 'checkLoginNeeded'; trong phương thức getSubscribeedEvents ().

Câu trả lời:


13

Cách đơn giản nhất là để browse đến /admin/config/system/site-informationvà điền vào các lĩnh vực mà đọc Default 403 (access denied) pagevớiuser/login


7
Đó là một giải pháp tốt nhưng nó không tính đến thực tế là người dùng có thể đã đăng nhập mà tôi đã đề cập trong phần mô tả.

13

Tôi đã thấy rằng câu hỏi này không bao giờ được trả lời làm thế nào để làm điều này lập trình. Mã thực sự hoạt động, khi được đặt trong một thuê bao ngoại lệ:

/src/EventSubscacker/RedirectOn403Subscacker.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.service.yml:

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

4
Điều này hoạt động và có lẽ là câu trả lời tốt nhất cho đến khi các mô-đun liên quan (Bao gồm các quy tắc) có bản phát hành ổn định. Tôi đã phải thêm -> toString () vào $ query ['Destination'] = Url :: fromRoute ('<current>') để làm việc này
Colin Shipton

2
Câu trả lời này xứng đáng để hiển thị cao hơn!
pbonnefoi

9

Chỉ cần nhìn vào tiêu đề của câu hỏi này (= Cách chuyển hướng người dùng đến biểu mẫu đăng nhập từ 403? ), Có 2 tùy chọn để làm như vậy, không có bất kỳ mã tùy chỉnh nào liên quan, như chi tiết bên dưới.

Tùy chọn 1: Sử dụng mô-đun CustomError

Các CustomError mô-đun cho phép quản trị trang web để tạo các trang lỗi tùy chỉnh cho HTTP mã trạng thái 403 (access denied) và 404 (không tìm thấy), mà không cần tạo nút cho mỗi người trong số họ. Một số chi tiết khác về các tính năng của nó (từ trang dự án của nó):

  • Tiêu đề và mô tả trang cấu hình.
  • Không có tiêu đề tác giả và ngày / thời gian như với các nút bình thường.
  • Bất kỳ văn bản định dạng HTML có thể được đặt trong thân trang.
  • Các trang lỗi là có thể.
  • Người dùng chưa đăng nhập và cố gắng truy cập vào một khu vực yêu cầu đăng nhập sẽ được chuyển hướng đến trang mà họ đang cố truy cập sau khi họ đăng nhập.
  • Cho phép chuyển hướng tùy chỉnh cho 404s.

Có lẽ bạn sẽ quan tâm chủ yếu đến phần " Người dùng chưa đăng nhập và cố gắng truy cập vào một khu vực yêu cầu đăng nhập sẽ được chuyển hướng đến trang mà họ đang cố truy cập sau khi họ đăng nhập. "

Đối với D8, cũng có phiên bản 8.x-1.x-dev cho mô-đun này, chi tiết hơn về nó có thể được tìm thấy trong Vấn đề # 2219227 .

Tùy chọn 2: Sử dụng mô-đun Quy tắc

Giả sử đường dẫn của trang "Mặc định 403" được đặt thành no_access(thông qua quản trị viên). Sau đó, tạo quy tắc bằng mô-đun Quy tắc , với sự kiện như "Sau khi truy cập nút no_access". Vì vậy, toàn bộ quy tắc sẽ trông giống như vậy:

  • Sự kiện: Sau khi truy cập nútno_access
  • Điều kiện:

    1. Người dùng có vai trò -Parameter: User: [site:current-user], Roles: anonymous user
    2. KHÔNG so sánh văn bản -Parameter: Text: [site:current-page:url], Matching text: user/login
  • Hành động: Chuyển hướng trang -Parameter: URL: user/login

Nếu bạn muốn làm như vậy, bạn thậm chí có thể thêm một Hành động khác để hiển thị một số tin nhắn (thông tin) trong vùng tin nhắn Drupal, với nội dung như "Bạn đã cố truy cập trang cần đăng nhập ...".

Đúng, nó có thể yêu cầu bạn kích hoạt một mô-đun đóng góp thêm ( Quy tắc ). Nhưng, như được chỉ ra bởi mức độ phổ biến ngày càng tăng của nó, mô-đun đó có thể đã được kích hoạt trong hầu hết mọi trang web (tương tự như mô-đun Lượt xem ), vì có hàng tá trường hợp sử dụng cho mô-đun này.

Đối với D8, cũng có phiên bản 8.x-3.x-alfa1 cho mô-đun này, chi tiết về phiên bản D8 của nó có thể được tìm thấy trong Vấn đề # 2574691 , bao gồm liên kết đến vấn đề Quy tắc " Quy tắc 8.x Lộ trình "

Nếu những điều trên không có ích, thì bạn có thể muốn kiểm tra xem lý do cho vòng lặp của bạn (hoặc "một số ưu tiên cao" như trong câu hỏi của bạn) không thể được ngăn chặn / giải thích bằng một câu tương tự như câu trả lời cho câu hỏi " Cách chỉ định một sự kiện Quy tắc như "Nội dung sẽ được xem"? ".


4

Tôi đoán giải pháp cho vấn đề của bạn là đơn giản. Bạn có thể dễ dàng tạo một trang tùy chỉnh 404403sau đó bên trong trang này, chuyển hướng người dùng ẩn danh đến /usertrang.

Bạn có thể sử dụng mã này

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

Bất cứ khi nào 404 xảy ra, bạn page--404.tpl.phpsẽ được sử dụng. Trong trang này sử dụng mã này

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

Trang Cách tạo 403 và 404 tùy chỉnh trong Drupal giải thích một phương pháp khác để tạo trang cho 403404.


5
Này bạn đời, bạn nên kiểm tra các thẻ và mã. Anh chàng này rõ ràng đang sử dụng Drupal 8.
alexej_d

1
xin chào, tôi đã đưa cho anh ta thuật toán, anh ta có thể dễ dàng thay đổi nó thành 8định dạng
M ama D

3

Cách dễ nhất để làm điều đó là sử dụng mô-đun Redirect 403 sang Đăng nhập người dùng (phiên bản dev của nó tồn tại cho D8). Đây là một trích dẫn về nó (từ trang dự án của nó):

Chuyển hướng trang lỗi HTTP 403 sang trang Drupal / user / login bằng một thông báo tùy chọn có nội dung:

"Truy cập bị từ chối! Bạn phải đăng nhập để xem trang này."

Ngoài ra, trang mong muốn được thêm vào chuỗi truy vấn url để khi đăng nhập thành công, người dùng sẽ được đưa trực tiếp đến nơi mà ban đầu họ đang cố gắng đi.


1
Tại sao câu trả lời này bị bỏ qua?
Miloš Kroulík

@ milos.kroulik Tôi đoán vì câu hỏi là về Drupal 8 nhưng mô-đun đó là dành cho 76
M ama D

1
Không có mô-đun nào có phiên bản Drupal 8 đang được phát triển
Colin Shipton

1
Khá chắc chắn rằng downvote là do câu trả lời là câu trả lời "chỉ liên kết" (một lý do điển hình cho câu trả lời bị hạ cấp hoặc thậm chí bị xóa ...). Những câu trả lời như vậy cũng thường xuất hiện trong hàng đánh giá "câu trả lời thấp" ... Hãy tham khảo phiên bản chỉnh sửa của câu trả lời này ngay bây giờ để biết thêm câu trả lời của nó (không còn có nguy cơ bị coi là câu trả lời chỉ liên kết).
Pierre.Vriens

Câu trả lời này không tính đến nếu người dùng đã đăng nhập hoặc nếu trang web đang sử dụng fast404 và 403.

0

(1) tạo một nút trang với bí danh như "/my403.html"

(2) truy cập / admin / config / system / site-information và đặt "/my403.html" là 403-Errorpage

(3) đi tới / admin / architecture / block và thêm khối "Đăng nhập người dùng" (Biểu mẫu thứ hai) vào vùng nội dung chính. Hạn chế sự xuất hiện của khối đối với trang "my403.html" và vai trò "khách".

Đó là nó.

Nếu bạn cần thêm quyền kiểm soát, hãy tạo bộ điều khiển cho trang 403 của bạn và thêm UserLoginForm bằng tay.

Trân trọng, Rainer

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.