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

응답에 이미 destination (current 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 [ 'destination'] = Url :: fromRoute ( '<current>')에 추가해야했습니다
— Colin Shipton

2
이 답변은 더 높게 나타날 가치가 있습니다!
— pbonnefoi

13

가장 쉬운 방법은 /admin/config/system/site-information다음 Default 403 (access denied) page으로 읽는 필드 를 찾아서 채우는 것입니다.user/login


7
그것은 좋은 해결책이지만 설명에서 언급 한 사용자가 이미 로그인했을 수 있다는 사실을 고려하지 않습니다.

9

이 질문의 제목 (= 403에서 로그인 양식으로 사용자를 리디렉션하는 방법? )을 살펴보면 아래에 설명 된 것처럼 사용자 정의 코드를 사용하지 않고 두 가지 옵션을 사용할 수 있습니다.

옵션 1 : CustomError 모듈 사용

인 CustomError 모듈은 사이트 관리자는 HTTP에 대한 사용자 지정 오류 페이지를 만들 수 있습니다 상태 403 (액세스 거부) 코드 404 (찾을 수 없음), 그들 각각의 노드를 만드는없이. 기능에 대한 자세한 내용은 (프로젝트 페이지에서) :

  • 구성 가능한 페이지 제목 및 설명.
  • 일반 노드와 마찬가지로 작성자 및 날짜 / 시간 헤더가 없습니다.
  • HTML 형식의 텍스트는 페이지 본문에 넣을 수 있습니다.
  • 오류 페이지가 있습니다.
  • 로그인하지 않은 상태에서 로그인이 필요한 영역에 액세스하려고하면 로그인 한 후 액세스하려는 페이지로 리디렉션됩니다.
  • 404에 대한 사용자 지정 리디렉션을 허용합니다.

" 로그인하지 않은 사용자가 로그인이 필요한 영역에 액세스하려고하면 로그인 한 후 액세스하려는 페이지로 리디렉션됩니다. "에 대한 부분에 관심이있을 것입니다 .

D8의 경우이 모듈에 사용할 수 있는 8.x-1.x-dev 버전 도 있으며, 자세한 내용은 Issue # 2219227 에서 찾을 수 있습니다 .

옵션 2 : 규칙 모듈 사용

"Default 403"페이지의 경로가 no_access(admin을 통해) 설정되어 있다고 가정하십시오 . 그런 다음 "노드 방문 후" 와 같은 이벤트 로 규칙 모듈을 사용하여 규칙을 작성하십시오 . 전체 규칙은 다음과 같습니다.no_access

  • 이벤트 : 노드 방문 후no_access
  • 정황:

    1. 사용자에게 역할이 있습니다 -Parameter: User: [site:current-user], Roles: anonymous user
    2. NOT 텍스트 비교 -Parameter: Text: [site:current-page:url], Matching text: user/login
  • 작업 : 페이지 리디렉션 -Parameter: URL: user/login

그렇게하려면 Drupal 메시지 영역에 "로그인이 필요한 페이지를 방문하려고했습니다 ..."와 같은 (정보) 메시지를 표시하는 다른 작업 을 추가 할 수도 있습니다 .

사실, 추가 기여 모듈 ( Rules ) 을 활성화해야 할 수도 있습니다 . 그러나 인기가 높아짐에 따라 해당 모듈은 수십 개의 유스 케이스가 있기 때문에 대부분의 사이트에서 ( Views 모듈 과 비슷한) 이미 사용 가능할 수 있습니다 .

D8의 경우이 모듈에 사용할 수 있는 8.x-3.x-alfa1 버전도 있습니다. D8 버전에 대한 자세한 내용은 규칙 번호 " 규칙 8.x 로드맵 "에 대한 링크가 포함 된 이슈 번호 2574691 에서 확인할 수 있습니다.

위에서되지 도움 않는 경우에, 당신은 루프의 이유 (또는 귀하의 질문과 같이 "일부 높은 우선 순위가")을 방지 할 수없는 경우 확인 할 수 있습니다 / 질문 '에 대한 답과 비슷한으로 설명 방법을 지정하려면 같은 규칙 이벤트? "내용은 볼 '될 것'이다" ".


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 페이지를 만들려면 위한 페이지를 만드는 다른 방법 설명 403및 404.


5
친구, 태그와 코드를 확인해야합니다. 이 사람은 Drupal 8을 분명히 사용하고 있습니다.
— alexej_d

1
안녕, 나는 그에게 알고리즘을 주었다, 그는 쉽게 8형식으로 변경할 수 있습니다
— M D D D

3

가장 쉬운 방법은 403을 사용자 로그인으로 리디렉션 모듈 (D8의 dev 버전)을 사용하는 것입니다. 다음은 프로젝트 페이지에서 이에 대한 인용입니다.

다음과 같은 선택적 메시지와 함께 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는 답변이 "링크 전용"답변 (답이 downvoted 또는 삭제 된 일반적인 이유)이기 때문에 발생했음을 확신하십시오. 이러한 답변은 일반적으로 "낮은 수준의 답변"검토 대기열에도 표시됩니다. 향상된 답변을 위해이 답변의 편집 된 버전을 참조하십시오 (더 이상 링크 전용 답변으로 간주 될 위험이 없음).
— Pierre.Vriens

이 답변은 사용자가 이미 로그인했거나 사이트에서 fast404 및 403을 사용중인 경우 고려하지 않습니다.

0

(1) "/my403.html"과 같은 별명으로 페이지 노드를 작성하십시오.

(2) / admin / config / system / site-information으로 이동하여 "/my403.html"을 403-Errorpage로 설정하십시오.

(3) / admin / structure / block으로 이동하여 "User login"블록 (Sec. Forms)을 기본 컨텐츠 영역에 추가하십시오. 블록 모양을 "my403.html"및 역할 "guest"로 제한하십시오.

그게 다야.

더 많은 제어가 필요하면 403 페이지에 대한 컨트롤러를 작성하고 수동으로 UserLoginForm을 추가하십시오.

안부 인사, 라이너

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.