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

나는 당신의 문제에 대한 해결책이 간단하다고 생각합니다. 에 대한 당신은 쉽게 사용자 정의 페이지를 만들 수 있습니다 404403다음이 페이지 내부의 익명 사용자를 리디렉션 /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 페이지를 만들려면 위한 페이지를 만드는 다른 방법 설명 403404.


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.