问题
In a TYPO3 6.1 site, I would like to make the creation of restricted (fe_groups) pages as easy as possible for editors. There's not one single protected area, but several protected pages all over the pagetree.
What I would like to achieve would be that whenever a page has some login behaviour/restriction and no valid fe_user is logged in, there is a redirection to a central login page.
I have found this post TYPO3 - Redirecting to login page when user is not logged in that refers to the same issue - but the solution requires setting PIDs by hand.
I can hardly believe that such a feature ("set target page for redirections based on access restrictions") is not available. Or does it exist, or is it on a roadmap somewhere? And if not, is there a workaround?
回答1:
This is indeed a big missing feature in TYPO3. The problem is that because of the way TYPO3 is built it's hard to determine whether a page doesn't exist (404) or access is forbidden (403). I did some further development of an unpublished extension that does the job, see https://github.com/phluzern/adfc_pagenotfound
In readme.txt you will find the configuration that is needed. It is in use with TYPO3 4.7, therefore some used classes may be deprecated or removed in 6.1. If so, fork the project, change them and make some pull requests so I can update it.
The extension makes use of a custom parameter $arPid (access restriction pid). The ID to the page that is access restricted is sent to the login page. Your login form must be able to handle this parameter in order to redirect, see an example here: https://github.com/phluzern/phzldap/blob/master/pi1/class.tx_phzldap_pi1.php#L133
It might be better to use a redirect_url as it is supported in felogin.
Update
In the meantime, I'm using an improved class with the following features:
- If access to page is forbidden, redirect to a login page with the standard
redirect_urlparameter. This allows a redirect after a successful fe login using EXT:felogin without modifications and also supports speaking URLs. - Redirect to 404 page if page is not found respecting the current language of the site.
The code is as follows:
<?php
use TYPO3\CMS\Core\Utility\GeneralUtility;
class user_pageNotFound {
/**
* Detect language and redirect to 404 error page
*
* @param array $params "currentUrl", "reasonText" and "pageAccessFailureReasons"
* @param \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController $tsfeObj
*/
public function pageNotFound($params, $tsfeObj) {
/*
* If a non-existing page with a RealURL path was requested (www.mydomain.tld/foobar), a fe_group value for an empty
* key is set:
* $params['pageAccessFailureReasons']['fe_group'][null] = 0;
* This is the reason why the second check was implemented.
*/
if (!empty($params['pageAccessFailureReasons']['fe_group']) && !array_key_exists(null, $params['pageAccessFailureReasons']['fe_group'])) {
// page access failed because of missing permissions
header('HTTP/1.0 403 Forbidden');
$this->initTSFE(1);
/** @var \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer $cObj */
$cObj = GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\ContentObject\\ContentObjectRenderer');
$loginUrl = $cObj->typoLink_URL(array(
'parameter' => $GLOBALS['TYPO3_CONF_VARS']['FE']['pageNotFound_handling_loginPageID'],
'useCacheHash' => FALSE,
'forceAbsoluteUrl' => TRUE,
'additionalParams' => '&redirect_url=' . $params['currentUrl']
));
TYPO3\CMS\Core\Utility\HttpUtility::redirect($loginUrl);
} else {
// page not found
// get first realurl configuration array (important for multidomain)
$realurlConf = array_shift($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['realurl']);
// look for language configuration
foreach ($realurlConf['preVars'] as $conf) {
if ($conf['GETvar'] == 'L') {
foreach ($conf['valueMap'] as $k => $v) {
// if the key is empty (e.g. default language without prefix), break
if (empty($k)) {
continue;
}
// we expect a part like "/de/" in requested url
if (GeneralUtility::isFirstPartOfStr($params['currentUrl'], '/' . $k . '/')) {
$tsfeObj->pageErrorHandler('/index.php?id=' . $GLOBALS['TYPO3_CONF_VARS']['FE']['pageNotFound_handling_redirectPageID'] . '&L=' . $v);
}
}
}
}
// handle default language
$tsfeObj->pageErrorHandler('/index.php?id=' . $GLOBALS['TYPO3_CONF_VARS']['FE']['pageNotFound_handling_redirectPageID']);
}
}
/**
* Initializes a TypoScript Frontend necessary for using TypoScript and TypoLink functions
*
* @param int $id
* @param int $typeNum
*/
protected function initTSFE($id = 1, $typeNum = 0) {
\TYPO3\CMS\Frontend\Utility\EidUtility::initTCA();
if (!is_object($GLOBALS['TT'])) {
$GLOBALS['TT'] = new \TYPO3\CMS\Core\TimeTracker\NullTimeTracker;
$GLOBALS['TT']->start();
}
$GLOBALS['TSFE'] = GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\Controller\\TypoScriptFrontendController', $GLOBALS['TYPO3_CONF_VARS'], $id, $typeNum);
$GLOBALS['TSFE']->sys_page = GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\Page\\PageRepository');
$GLOBALS['TSFE']->sys_page->init(TRUE);
$GLOBALS['TSFE']->connectToDB();
$GLOBALS['TSFE']->initFEuser();
$GLOBALS['TSFE']->determineId();
$GLOBALS['TSFE']->initTemplate();
$GLOBALS['TSFE']->rootLine = $GLOBALS['TSFE']->sys_page->getRootLine($id, '');
$GLOBALS['TSFE']->getConfigArray();
if (\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded('realurl')) {
$rootline = \TYPO3\CMS\Backend\Utility\BackendUtility::BEgetRootLine($id);
$host = \TYPO3\CMS\Backend\Utility\BackendUtility::firstDomainRecord($rootline);
$_SERVER['HTTP_HOST'] = $host;
}
}
}
The only thing you need to configure are the PIDs of the page not found and login pages:
// ID of the page to redirect to if page was not found
$GLOBALS['TYPO3_CONF_VARS']['FE']['pageNotFound_handling_redirectPageID'] = 4690;
// ID of the page to redirect to if current page is access protected
$GLOBALS['TYPO3_CONF_VARS']['FE']['pageNotFound_handling_loginPageID'] = 5404;
来源:https://stackoverflow.com/questions/20093651/how-to-define-redirect-page-for-protected-pages