如何在自定义TYPO3 ViewHelper中生成URL的cHash用于<a>标签
在TYPO3自定义ViewHelper中生成带cHash的标签
1. 哪些URL部分需要参与cHash计算?
需要包含所有影响页面内容的GET参数,也就是你URL里的tx_review_listreviews[action]和tx_review_listreviews[controller],另外必须加上当前页面的id参数(即使URL里没显式写出,也要从当前请求中获取)。注意:
- 不包含
cHash本身 - 参数顺序对cHash计算结果有影响,必须保持一致
- 若有语言参数
L,也需要纳入计算
2. ViewHelper内部生成cHash的正确方式
绝对不能自己用md5手动生成!TYPO3的cHash并非简单哈希,它结合了站点加密密钥、页面ID、参数组合等多维度信息,手动生成会导致cHash验证失败,页面返回403。
可用的内置方法
ViewHelper中推荐直接使用UriBuilder类构建URL,它会自动处理参数排序、cHash生成等所有细节;也可以通过HashService手动生成cHash,但这种方式出错概率更高,仅作了解即可。
3. 示例代码
方式一:使用UriBuilder(推荐,自动处理cHash)
<?php namespace Vendor\Review\ViewHelpers; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractTagBasedViewHelper; use TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder; class ReviewLinkViewHelper extends AbstractTagBasedViewHelper { protected $tagName = 'a'; public function initializeArguments() { parent::initializeArguments(); $this->registerArgument('text', 'string', '链接文本', true); } public function render() { /** @var UriBuilder $uriBuilder */ $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class); // 从当前请求获取页面ID,也可手动指定固定页面ID $pageId = $this->renderingContext->getRequest()->getPageUid(); // 构建带参数的URL,UriBuilder会自动生成cHash $uri = $uriBuilder ->reset() ->setTargetPageUid($pageId) ->setArguments([ 'tx_review_listreviews' => [ 'action' => 'list', 'controller' => 'Reviews' ] ]) ->build(); // 设置<a>标签属性与内容 $this->tag->addAttribute('href', $uri); $this->tag->setContent($this->arguments['text']); return $this->tag->render(); } }
方式二:手动用HashService生成cHash(不推荐)
<?php namespace Vendor\Review\ViewHelpers; use TYPO3\CMS\Core\Security\HashService; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractTagBasedViewHelper; class ReviewLinkViewHelper extends AbstractTagBasedViewHelper { protected $tagName = 'a'; public function initializeArguments() { parent::initializeArguments(); $this->registerArgument('text', 'string', '链接文本', true); } public function render() { $pageId = $this->renderingContext->getRequest()->getPageUid(); // 整理参与cHash计算的参数,顺序必须和最终URL一致 $params = [ 'id' => $pageId, 'tx_review_listreviews[action]' => 'list', 'tx_review_listreviews[controller]' => 'Reviews' ]; // 转换为标准查询字符串格式 $queryString = http_build_query($params, '', '&', PHP_QUERY_RFC3986); /** @var HashService $hashService */ $hashService = GeneralUtility::makeInstance(HashService::class); // 生成合法cHash $cHash = $hashService->generateHmac($queryString); // 拼接最终URL $url = sprintf('/sonstiges/test?%s&cHash=%s', $queryString, $cHash); $this->tag->addAttribute('href', $url); $this->tag->setContent($this->arguments['text']); return $this->tag->render(); } }
关键注意事项
- 禁止手动用md5生成cHash:TYPO3的cHash依赖站点专属的
encryptionKey(存储在LocalConfiguration.php中),md5无法匹配其生成逻辑,会导致验证失败。 - 优先使用UriBuilder:它会自动处理参数排序、语言参数、cHash生成等细节,避免手动拼接的错误。
- 必须包含页面ID:cHash计算必须关联当前页面的
id参数,否则生成的cHash无效。
内容的提问来源于stack exchange,提问作者Georgio
相关产品推荐
相关产品推荐

