bedita / web-tools
用于使用 BEdita API 的 CakePHP 应用程序的工具
Requires
- php: ^7.4 || ^8.0
- bedita/php-sdk: ^3.1.0
- cakephp/cakephp: ^4.2.2
- cakephp/twig-view: ^1.3.0
- firebase/php-jwt: ^6.9
Requires (Dev)
- cakephp/authentication: ^2.9
- cakephp/authorization: ^2.2
- cakephp/cakephp-codesniffer: ~4.5.1
- josegonzalez/dotenv: ^3.2
- league/oauth2-client: ^2.6
- phpstan/extension-installer: ^1.0
- phpstan/phpstan: ^1.8
- phpstan/phpstan-deprecation-rules: ^1.0
- phpunit/phpunit: ^9.5
Suggests
- cakephp/authentication: ^2.9 To use "ApiIdentifier", "Identity", "IdentityHelper" and other authentication features
- cakephp/authorization: ^2.2 To use "RequestPolicy" and other authorization features
- dev-master
- v4.0.2
- v4.0.1
- v4.0.0
- v3.13.0
- v3.12.1
- v3.12.0
- v3.11.0
- v3.10.2
- v3.10.1
- v3.10.0
- v3.9.0
- v3.8.1
- v3.8.0
- v3.7.1
- v3.7.0
- v3.6.2
- v3.6.1
- v3.6.0
- v3.5.1
- v3.5.0
- v3.4.0
- v3.3.0
- v3.2.0
- v3.1.4
- v3.1.3
- v3.1.2
- v3.1.1
- v3.1.0
- v3.0.1
- v3.0.0
- v2.5.0
- v2.4.3
- v2.4.2
- v2.4.1
- v2.4.0
- v2.3.0
- v2.2.0
- v2.0.0
- 1.x-dev
- v1.9.1
- v1.9.0
- v1.8.0
- v1.7.1
- v1.7.0
- v1.6.1
- v1.6.0
- v1.5.0
- v1.4.3
- v1.4.2
- v1.4.1
- v1.4.0
- v1.3.0
- v1.2.0
- v1.1.1
- v1.1.0
- v1.0.3
- v1.0.2
- v1.0.1
- v1.0.0
This package is auto-updated.
Last update: 2024-09-16 10:21:40 UTC
README
安装
首先,如果 vendor
目录尚未创建,您必须使用以下命令安装 composer 依赖项
composer install
您可以使用 composer 将此插件安装到您的 CakePHP 应用程序中。
安装 composer 包的推荐方法是
composer require bedita/web-tools
辅助工具
Web 组件
此助手提供了一些方法,通过在客户端 JavaScript 组件中设置一些应用变量来设置自定义元素。它旨在避免使用声明性赋值到 HTML 节点来生成内联 JS 字典或变量。字符串和数值作为节点属性添加,而对象和数组使用内联脚本。
示例
在 webroot/js
中创建一个包含自定义元素定义的 js 文件
webroot/js/components/awesome-video.js
class AwesomeVideo extends HTMLElement { connectedCallback() { this.video = document.createElement('video'); this.video.src = this.getAttribute('src'); this.appendChild(this.video); } } customElements.define('awesome-video', AwesomeVideo);
现在您可以在 twig 模板中初始化元素
templates/Pages/document.twig
{{ WebComponents.element('awesome-video', { src: attach.uri }, 'components/awesome-video') }}
您还可以通过使用 is
方法扩展原生标签,以便设置与 is
方法简单交互
webroot/js/components/awesome-table.js
class AwesomeTable extends HTMLElement { connectedCallback() { this.addEventListener('click', (event) => { let th = event.target.closest('[sort-by]'); if (th) { this.sortBy(th.getAttribute('sort-by')); } }): } sortBy(field) { // ... } } customElements.define('awesome-table', AwesomeTable, { extends: 'table' });
templates/Pages/users.twig
<table {{ WebComponents.is('awesome-table', {}, 'components/awesome-table')|raw }}> <thead> <th>Email</th> <th>Name</th> </thead> <tbody> {% for user in users %} <tr> <td>{{ user.attributes.email }}</td> <td>{{ user.attributes.name }}</td> </tr> {% endfor %} </tbody> </table>
使用 AssetRevisions 加载资源
AssetRevisions
通过资产策略可以帮助轻松解决加载构建版本化资源(如 js
和 css
)的常见问题。
通过 \BEdita\WebTools\View\Helper\HtmlHelper
,您可以透明地链接放置在自定义文件夹中或生活在 webroot/js
或 webroot/css
中的原始资源。
定义要使用的策略
定义应用程序将使用哪种策略的最佳位置是 Application::bootstrap()
。
use BEdita\WebTools\Utility\AssetRevisions; use BEdita\WebTools\Utility\Asset\Strategy\EntrypointsStrategy; public function bootstrap(): void { parent::bootstrap(); AssetsRevisions::setStrategy(new EntrypointsStrategy()); // you can also set the path where to find the manifest (default is webroot/build/entrypoints.json) // AssetsRevisions::setStrategy( // new EntrypointsStrategy(['manifestPath' => '/custom/path/entrypoints.json']); // ); }
有三种资产策略可用
- 基于由 Webpack Encore 生成的
entrypoints.json
文件的EntrypointsStrategy
- 基于由 gulp-rev 生成的
rev-manifest.json
文件的RevManifestStrategy
无论如何,您都可以通过实现 AssetStrategyInterface
来定义自己的策略。
使用 HtmlHelper 加载资源
一旦设置策略,您就可以使用 \BEdita\WebTools\View\Helper\HtmlHelper
及其方法 script()
、css()
和 assets()
链接资源,例如
<?= $this->Html->script('app') ?>
将首先从您的资产策略中搜索 app
资产,如果策略无法解析资产,则回退到 CakePHP HtmlHelper
。
这样,您可以继续以在常见的 webroot/js
或 webroot/css
中放置的方式加载资源,并将解析链接的任务委托给 \BEdita\WebTools\View\Helper\HtmlHelper
。
标识符
ApiIdentifier
ApiIdentifier
是 标识符,它帮助通过 BEdita API 识别 Authentication 插件。
为了使用标识符,您需要在 Application.php
应用程序引导中安装和加载 Authentication 插件
安装
composer require cakephp/authentication
然后在应用中加载
public function bootstrap(): void { parent::bootstrap(); $this->addPlugin('Authentication'); }
然后添加 AuthenticationMiddleware
public function middleware(MiddlewareQueue $middlewareQueue): MiddlewareQueue { // Various other middlewares for error handling, routing etc. added here. // Create an authentication middleware object $authentication = new AuthenticationMiddleware($this); // Add the middleware to the middleware queue. // Authentication should be added *after* RoutingMiddleware. // So that subdirectory information and routes are loaded. $middlewareQueue->add($authentication); return $middlewareQueue; }
并利用 getAuthenticationService()
钩子来设置标识符。
public function getAuthenticationService(ServerRequestInterface $request): AuthenticationServiceInterface { $service = new AuthenticationService(); // Load the authenticators, you want session first $service->loadAuthenticator('Authentication.Session'); $service->loadAuthenticator('Authentication.Form', [ 'loginUrl' => '/users/login' ]); // Load identifiers $service->loadIdentifier('BEdita/WebTools.Api'); return $service; }
身份和身份助手
要使用它们,请确保安装 Authentication 插件
composer require cakephp/authentication
并在 Application::bootstrap()
中加载插件 $this->addPlugin('Authentication')
。
然后设置您的应用程序以使用 Identity
,例如
// Edit Application.php public function getAuthenticationService(ServerRequestInterface $request): AuthenticationServiceInterface { $service = new AuthenticationService([ 'identityClass' => \BEdita\WebTools\Identity::class ]); // Load the authenticators, you want session first $service->loadAuthenticator('Authentication.Session'); $service->loadAuthenticator('Authentication.Form'); // Load identifiers $service->loadIdentifier('BEdita/WebTools.Api'); return $service; }
Identity
提供了一个方便的 hasRole()
方法
// in a Controller $identity = $this->Authentication->getIdentity(); if ($identity->hasRole('admin')) { $this->Flash->success('Hi admin!'); }
IdentityHelper
允许将配置的方法委派给 Identity
,例如在 TwigView
模板中
{% if Identity.hasRole('basic') %} <button type="button">Upgrade to premium</button> {% endif %}
请求策略
使用 RequestPolicy
类,可以通过身份的角色或自定义策略规则设置对控制器和操作的访问。
首先安装 Authorization 插件
composer require cakephp/authorization
并在 Application::bootstrap()
中加载插件 $this->addPlugin('Authorization')
。
然后在 Application
类中设置策略。添加 AuthorizationMiddleware
和 RequestAuthorizationMiddleware
public function middleware(MiddlewareQueue $middlewareQueue): MiddlewareQueue { // other middleware... // $middlewareQueue->add(new AuthenticationMiddleware($this)); // Add authorization (after authentication if you are using that plugin too). $middlewareQueue->add(new AuthorizationMiddleware($this)); $middlewareQueue->add(new RequestAuthorizationMiddleware()); }
并配置策略
public function getAuthorizationService(ServerRequestInterface $request): AuthorizationServiceInterface { $mapResolver = new MapResolver(); $mapResolver->map( ServerRequest::class, new RequestPolicy([ // setup your request policy rules 'rules' => [ 'Dashboard' => [ 'index' => ['premium', 'basic'], // allow access to DashboardController::index() for these roles 'special' => 'premium', // allow access to Dashboard::special() only for 'premium' role '*' => false, // fallback for other DashboardController actions. Forbidden to all ], ], ]); ); return new AuthorizationService($mapResolver); }
OAuth2 设置
使用提供的 OAuth2 工具的快速步骤。
- 在
config/routes.php
中创建一个指向类似/ext/login/{provider}
的路径,以与所选的 OAuth2 提供者交互。每个{provider}
必须与配置中指定的提供者配置键匹配,例如下面配置示例中的google
,请参阅 OAuth2 提供者结构。以下是一个示例
$builder->connect( '/ext/login/{provider}', ['controller' => 'ExternalLogin', 'action' => 'login'], ['_name' => 'login:oauth2'] );
- 为上述路由规则定义一个控制器。登录操作的简化版本可以包含如下示例中的简单重定向
public function login(): ?Response { $result = $this->Authentication->getResult(); if (!empty($result) && $result->isValid()) { $target = $this->Authentication->getLoginRedirect() ?? ['_name' => 'home']; return $this->redirect($target); } // Handle authentication failure below with flash messages, logs, redirects... // .... }
-
在您的主
Application
类中设置OAuth2Authenticator
和OAuth2Identifier
类,并创建相应的OAuth2Providers
配置。下面段落中有更多详细信息。 -
在
Application::middleware()
中将OAuth2Middleware
添加到中间件堆栈中,紧随AuthenticationMiddleware
之后,如下所示
->add(new AuthenticationMiddleware($this)) ->add(new OAuth2Middleware())
OAuth2 提供者
要使用 OAuth2Authenticator
和 OAuth2Identifier
类,您必须在将此类加载到身份验证服务中时传递支持的 OAuth2 提供者配置。以下是一个在 Application::getAuthenticationService()
中如何操作的简要示例
$service = new AuthenticationService(); $path = $request->getUri()->getPath(); if (strpos($path, '/ext/login') === 0) { $providers = (array)Configure::read('OAuth2Providers'); $service->loadIdentifier('BEdita/WebTools.OAuth2', compact('providers') + [ 'autoSignup' => true, 'signupRoles' => ['customer'], ]); $service->loadAuthenticator('BEdita/WebTools.OAuth2', compact('providers') + [ 'redirect' => ['_name' => 'login:oauth2'], ]); }
我们仅在请求路径与上面定义的 OAuth2 登录路由匹配时设置 OAuth2 验证器和标识符。
建议使用配置键如 OAuth2Providers
来存储提供者信息,但您必须使用 providers
键传递提供者设置数组。其他可能的配置是
- (
OAuth2Authenticator
)'redirect'
- 默认['_name' => 'login']
,指定为命名数组的重定向 URL 路由 - (
OAuth2Identifier
)autoSignup
- 默认false
,如果希望登录失败时执行自动注册,则设置为true
- (
OAuth2Identifier
)'signupRoles'
- 默认[]
,在注册过程中使用的用户角色,仅当autoSignup
为true
时使用
OAuth2 提供者结构
以下示例中的提供者配置结构如下。这里定义了一个单个的 google
提供者。必选配置键是 class
、setup
、options
和 map
,下面将解释。每个提供者键必须与在 BEdita API 中定义和配置的 auth_provider
名称匹配。
'google' => [ // OAuth2 class name, must be a supported provider of `league/oauth2-client` // see https://oauth2-client.thephpleague.com/providers/league/ official or third-party 'class' => '\League\OAuth2\Client\Provider\Google', // Provider class setup parameters, normally this includes `clientId` and `clientSecret` keys // Other parameters like 'redirectUri' will be added dynamically 'setup' => [ 'clientId' => '####', 'clientSecret' => '####', ], // Provider authorization options, specify the user information scope that you want to read // `'scope'` array will vary between providers, please read the oauth2-client documentation. 'options' => [ 'scope' => ['https://www.googleapis.com/auth/userinfo.email'], ], // Map BEdita user fields with auth provider data path, using dot notation like 'user.id' // In this array keys are BEdita fields, and values are paths to extract the desired item from the provider response // only `'provider_username'` is mandatory, to uniquely identify the user in the provider context // other fields could be used during signup 'map' => [ 'provider_username' => 'sub', 'username' => 'email', 'email' => 'email', 'name' => 'given_name', 'surname' => 'family_name', ], ],
有关 OAuth2 提供者配置的简要参考,请参阅 OAuth2 提供者配置 Wiki 页面