stevebauman / purify
Laravel 的 HTML 清理/消毒器
Requires
- php: >=7.4
- ezyang/htmlpurifier: ^4.17
- illuminate/contracts: ^7.0|^8.0|^9.0|^10.0|^11.0
- illuminate/support: ^7.0|^8.0|^9.0|^10.0|^11.0
Requires (Dev)
- orchestra/testbench: ^5.0|^6.0|^7.0|^8.0|^9.0
- phpunit/phpunit: ^8.0|^9.0|^10.0
README
A Laravel 的 HTMLPurifier 包装器,由 ezyang 开发 HTMLPurifier。
索引
需求
- PHP >= 7.4
- Laravel >= 7.0
安装
要在项目中安装 Purify,请在项目根目录下运行以下命令
composer require stevebauman/purify
然后,使用以下命令发布配置文件
php artisan vendor:publish --provider="Stevebauman\Purify\PurifyServiceProvider"
用法
清理字符串
要清理用户输入,只需使用 clean 方法
use Stevebauman\Purify\Facades\Purify; $input = '<script>alert("Harmful Script");</script> <p style="border:1px solid black" class="text-gray-700">Test</p>'; // Returns '<p>Test</p>' $cleaned = Purify::clean($input);
清理数组
需要净化用户输入的数组?只需传递一个数组即可
use Stevebauman\Purify\Facades\Purify; $array = [ '<script>alert("Harmful Script");</script> <p style="border:1px solid black" class="text-gray-700">Test</p>', '<script>alert("Harmful Script");</script> <p style="border:1px solid black" class="text-gray-700">Test</p>', ]; $cleaned = Purify::clean($array); // array [ // '<p>Test</p>', // '<p>Test</p>', // ] var_dump($cleaned);
动态配置
需要为单个输入使用不同的配置?将配置数组传递到第二个参数
注意:传递到第二个参数的配置不会与您的默认配置合并。
use Stevebauman\Purify\Facades\Purify; $config = ['HTML.Allowed' => 'div,b,a[href]']; $cleaned = Purify::config($config)->clean($input);
配置
在配置文件中,可以指定多个 HTMLPurifier 配置集,类似于 Laravel 内置的 database
、mail
和 logging
配置。只需调用 Purify::config($name)->clean($input)
来使用另一组配置。
例如,如果我们需要一个单独的配置来为评论系统,我们可以在 config/purify.php
文件中设置此配置
// config/purify.php 'configs' => [ // ... 'comments' => [ // Some configuration ... ], ]
然后,通过其名称在任何地方利用它
use Stevebauman\Purify\Facades\Purify; $cleanedContent = Purify::config('comments')->clean(request('content'));
有关 HTMLPurifier 配置文档,请访问 HTMLPurifier 网站
http://htmlpurifier.org/live/configdoc/plain.html
缓存
运行 Purify 一次后,HTMLPurifier 将自动将您的序列化 definitions
缓存到在 config/purify.php
中配置的 serializer.cache
定义中。
重要
如果您已将 Purify 配置为在 serializer
选项中使用 CacheDefinitionCache
,则此命令将在您配置其使用的缓存驱动程序上发出 Cache::clear()
。
如果您已将 Purify 配置为在 serializer
选项中使用 FilesystemDefinitionCache
,则此命令将清除您配置其存储的目录。
如果您打算使用此命令清除序列化定义,建议为 Purify 设置唯一的文件系统路径或磁盘(通过 config/filesystems.php
)或缓存存储(通过 config/cache.php
)。
如果您更新了 definitions
配置选项,则必须清除此 HTMLPurifier 缓存。
您可以通过 purify:clear
命令这样做
php artisan purify:clear
禁用缓存
要完全禁用缓存,您可以将 serializer
路径设置为 null
// config/purify.php 'serializer' => null,
这将导致您的定义在每个应用程序请求上序列化。
这对于调试或调整定义文件以查看即时结果特别有用。
重要
在生产环境中推荐使用缓存。
实践
如果您正在考虑消毒,您可能希望消毒存储在数据库中的用户 HTML 内容,然后将其渲染到您的应用程序中。
在此场景中,最佳实践可能在输出时进行清理,而不是输入时。数据库对包含的文本内容并不关心。
这样,您可以允许任何内容被插入数据库,并在输出时使用强大的清理规则。
要实现这一点,您可以在Eloquent模型上使用提供的PurifyHtmlOnGet
转换类。
use Stevebauman\Purify\Casts\PurifyHtmlOnGet; class Post extends Model { protected $casts = [ 'content' => PurifyHtmlOnGet::class, ]; }
或者,通过Eloquent属性转换器自行实现。
use Stevebauman\Purify\Facades\Purify; class Post extends Model { public function getContentAttribute($value) { return Purify::clean($value); } }
您甚至可以通过将配置名称附加到转换来配置用于转换的配置。
// config/purify.php 'configs' => [ // ... 'other' => [ // Some configuration ... ], ]
protected $casts = [ 'content' => PurifyHtmlOnGet::class.':other', ];
如果以后更改清理要求,这将非常有帮助,因为所有渲染的内容都将遵循这些清理规则。
如果您在设置值时想清理HTML,可以使用逆转换PurifyHtmlOnSet
。
自定义HTML定义
HTML.Doctype
配置选项表示最终遵守的架构。您可能希望通过指定自定义HTML元素“定义”来扩展这些架构定义以支持自定义元素或属性(例如,<foo>...</foo>
或<span foo="...">
)。
Purify提供了HTMLPurifier尚未支持的额外HTML5定义(通过Html5Definition
类)。
要创建自己的HTML定义,创建一个新类并使其实现Definition
。
namespace App; use HTMLPurifier_HTMLDefinition; use Stevebauman\Purify\Definitions\Definition; class CustomDefinition implements Definition { /** * Apply rules to the HTML Purifier definition. * * @param HTMLPurifier_HTMLDefinition $definition * * @return void */ public static function apply(HTMLPurifier_HTMLDefinition $definition) { // Customize the HTML purifier definition. } }
然后,在config/purify.php
文件中的definitions
键中引用此类。
// config/purify.php 'definitions' => \App\CustomDefinitions::class,
如果您想扩展内置的默认Html5Definition
,您可以将它应用到您的自定义定义中。
use Stevebauman\Purify\Definitions\Html5Definition; class CustomDefinition implements Definition { public static function apply(HTMLPurifier_HTMLDefinition $definition) { Html5Definition::apply($definition); // ... } }
Basecamp Trix 定义
以下是一个示例,说明如何自定义定义以支持Basecamp的Trix WYSIWYG编辑器(归功于Antonio Primera和Daniel Sun)
namespace App; use HTMLPurifier_HTMLDefinition; use Stevebauman\Purify\Definitions\Definition; class TrixPurifierDefinitions implements Definition { /** * Apply rules to the HTML Purifier definition. * * @param HTMLPurifier_HTMLDefinition $definition * * @return void */ public static function apply(HTMLPurifier_HTMLDefinition $definition) { $definition->addElement('figure', 'Inline', 'Inline', 'Common'); $definition->addAttribute('figure', 'class', 'Class'); $definition->addAttribute('figure', 'data-trix-attachment', 'Text'); $definition->addAttribute('figure', 'data-trix-attributes', 'Text'); $definition->addElement('figcaption', 'Inline', 'Inline', 'Common'); $definition->addAttribute('figcaption', 'class', 'Class'); $definition->addAttribute('figcaption', 'data-trix-placeholder', 'Text'); $definition->addAttribute('a', 'rel', 'Text'); $definition->addAttribute('a', 'tabindex', 'Text'); $definition->addAttribute('a', 'contenteditable', 'Enum#true,false'); $definition->addAttribute('a', 'data-trix-attachment', 'Text'); $definition->addAttribute('a', 'data-trix-content-type', 'Text'); $definition->addAttribute('a', 'data-trix-id', 'Number'); $definition->addElement('span', 'Block', 'Flow', 'Common'); $definition->addAttribute('span', 'data-trix-cursor-target', 'Enum#right,left'); $definition->addAttribute('span', 'data-trix-serialize', 'Enum#true,false'); $definition->addAttribute('img', 'data-trix-mutable', 'Enum#true,false'); $definition->addAttribute('img', 'data-trix-store-key', 'Text'); } }
自定义CSS定义
可以覆盖CSS定义,这允许您自定义允许的行内样式及其属性和值。这可以帮助填充诸如text-align等属性的缺失值,该属性的默认值是缺失开始和结束值。您可以通过创建CSS定义来完成此操作。
要创建自己的CSS定义,创建一个新类并使其实现CssDefinition
。
namespace App; use HTMLPurifier_CSSDefinition; use Stevebauman\Purify\Definitions\CssDefinition; class CustomCssDefinition implements CssDefinition { /** * Apply rules to the CSS Purifier definition. * * @param HTMLPurifier_CSSDefinition $definition * * @return void */ public static function apply(HTMLPurifier_CSSDefinition $definition) { // Customize the CSS purifier definition. $definition->info['text-align'] = new \HTMLPurifier_AttrDef_Enum( ['right', 'left', 'center', 'start', 'end'], false, ); } }
然后,在config/purify.php
文件中的css-definitions
键中引用此类。
// config/purify.php 'css-definitions' => \App\CustomCssDefinition::class,
请参阅HTMLPurifier库中的HTMLPurifier_CSSDefinition类以获取其他可以更改的示例。
从 v4 升级到 v5
要从v4升级,请在项目根目录中运行以下命令来安装最新版本
composer require stevebauman/purify
然后,导航到您的已发布config/purify.php
配置文件并复制settings
数组--除了以下键
HTML.DocType
:Core.Encoding
:Cache.SerializerPath
:
'settings' => [ - 'Core.Encoding' => 'utf-8', - 'Cache.SerializerPath' => storage_path('app/purify'), - 'HTML.Doctype' => 'XHTML 1.0 Strict', + 'HTML.Allowed' => 'h1,h2,h3,h4,h5,h6,b,strong,i,em,a[href|title],ul,ol,li,p[style],br,span,img[width|height|alt|src]', + 'HTML.ForbiddenElements' => '', + 'CSS.AllowedProperties' => 'font,font-size,font-weight,font-style,font-family,text-decoration,padding-left,color,background-color,text-align', + 'AutoFormat.AutoParagraph' => false, + 'AutoFormat.RemoveEmpty' => false, ],
重要:如果您已为
Cache.SerializerPath
创建唯一的存储路径,请注意这一点,以便您可以将其迁移到新的配置文件。
复制后,删除config/purify.php
文件,并运行以下命令
php artisan vendor:publish --provider="Stevebauman\Purify\PurifyServiceProvider"
然后,在新的config/purify.php
配置文件中,将键粘贴到(覆盖当前)configs.default
数组中
'configs' => [ 'default' => [ 'Core.Encoding' => 'utf-8', 'HTML.Doctype' => 'HTML 4.01 Transitional', + 'HTML.Allowed' => 'h1,h2,h3,h4,h5,h6,b,strong,i,em,a[href|title],ul,ol,li,p[style],br,span,img[width|height|alt|src]', + 'HTML.ForbiddenElements' => '', + 'CSS.AllowedProperties' => 'font,font-size,font-weight,font-style,font-family,text-decoration,padding-left,color,background-color,text-align', + 'AutoFormat.AutoParagraph' => false, + 'AutoFormat.RemoveEmpty' => false, ], ],
如果您已创建唯一的序列化器路径(以前通过上述旧的Cache.SerializerPath
配置键设置),则可以在新的serializer
配置键中重新配置此路径。
'serializer' => storage_path('app/purify'),
一切就绪!
从 v5 升级到 v6
在v6中,HTMLPurifier序列化器存储机制已更新以支持Laravel Vapour,允许您将序列化的HTMLPurifier定义存储在Redis缓存或外部文件系统中。
要从v5版本升级,请在项目的根目录下运行以下命令以安装最新版本
composer require stevebauman/purify
然后,进入您发布的 config/purify.php
配置文件,并将 serializer
配置选项替换为以下内容
- 'serializer' => storage_path('app/purify'), + 'serializer' => [ + 'disk' => env('FILESYSTEM_DISK', 'local'), + 'path' => 'purify', + 'cache' => \Stevebauman\Purify\Cache\FilesystemDefinitionCache::class, + ], + + // 'serializer' => [ + // 'driver' => env('CACHE_DRIVER', 'file'), + // 'cache' => \Stevebauman\Purify\Cache\CacheDefinitionCache::class, + // ],
这将更新控制序列化器缓存机制的语法。如果您想使用 Laravel 缓存驱动器(如 Redis)来存储序列化定义,现在可以取消注释下面的 serializer
缓存定义。