无需客户端凭证,从CLI调用Shopware API的认证方案咨询
免手动凭证的Shopware API CLI认证方案
针对在未登录状态下通过CLI调用Shopware API的需求,这里提供几个比手动生成集成凭证更优的自动化方案,覆盖不同场景需求:
方案1:插件自动生成并管理集成凭证(优化你的初始思路)
你提到的插件自动生成集成的思路可行,但可以优化生命周期管理,避免残留无用数据:
- 实现步骤:
- 在插件的
activate方法中,通过IntegrationRepository创建专属集成,只分配必要的API权限(遵循最小权限原则)。 - 生成的
clientId和clientSecret直接存入插件配置表,无需用户手动复制。 - 在插件的
deactivate或uninstall方法中,自动删除该集成,避免系统残留无用条目。
- 在插件的
- 代码示例:
public function activate(ActivateContext $context): void { parent::activate($context); $integrationRepository = $this->container->get(IntegrationRepository::class); $integration = $integrationRepository->create([ 'label' => 'CLI API Integration (Auto-Generated)', 'accessKey' => Uuid::randomHex(), 'secretAccessKey' => Uuid::randomHex(), 'permissions' => ['product:read', 'order:write'], // 按需设置权限 'active' => true, ], $context->getContext()); // 存入插件配置 $configService = $this->container->get(PluginConfigService::class); $pluginId = $context->getPlugin()->getId(); $configService->set('cliApiClientId', $integration->getAccessKey(), $pluginId); $configService->set('cliApiClientSecret', $integration->getSecretAccessKey(), $pluginId); } public function uninstall(UninstallContext $context): void { parent::uninstall($context); $integrationRepository = $this->container->get(IntegrationRepository::class); $integrations = $integrationRepository->search( (new Criteria())->addFilter(new EqualsFilter('label', 'CLI API Integration (Auto-Generated)')), $context->getContext() ); foreach ($integrations as $integration) { $integrationRepository->delete([$integration->getId()], $context->getContext()); } // 清理插件配置 $configService = $this->container->get(PluginConfigService::class); $pluginId = $context->getPlugin()->getId(); $configService->delete('cliApiClientId', $pluginId); $configService->delete('cliApiClientSecret', $pluginId); }
- 优缺点:
- 优点:完全自动化,用户激活插件即可使用;权限精准可控,降低安全风险。
- 缺点:凭证存储在数据库插件配置中,若数据库泄露可能导致凭证丢失;插件卸载后凭证会被删除,需提前备份。
方案2:使用Shopware原生CLI用户令牌(更贴合CLI场景)
Shopware支持为用户生成个人访问令牌(Personal Access Token),可直接用于CLI调用API,无需创建集成:
- 实现步骤:
- 通过插件或CLI命令自动创建专门用于CLI的用户,分配API相关权限。
- 生成该用户的个人访问令牌,将令牌存入系统环境变量(如
.env),避免明文存储。 - 在CLI脚本中,直接使用该令牌作为
Authorization: Bearer <token>头调用API。
- 代码示例(生成令牌):
// 自定义CLI命令中生成令牌 public function execute(InputInterface $input, OutputInterface $output): int { $userRepository = $this->container->get(UserRepository::class); $context = Context::createDefaultContext(); $user = $userRepository->search( (new Criteria())->addFilter(new EqualsFilter('username', 'cli_api_user')), $context )->first(); if (!$user) { // 创建CLI专用用户 $user = $userRepository->create([ 'username' => 'cli_api_user', 'password' => Uuid::randomHex(), // 随机密码,无需后台登录 'active' => true, 'permissions' => ['product:read', 'order:write'], ], $context); } // 生成个人访问令牌 $tokenRepository = $this->container->get(UserAccessTokenRepository::class); $token = $tokenRepository->create([ 'userId' => $user->getId(), 'name' => 'CLI API Token', 'token' => Uuid::randomHex(), 'expiresAt' => (new DateTime())->modify('+1 year'), // 设置过期时间 ], $context); // 将令牌写入.env文件 $envPath = $this->container->getParameter('kernel.project_dir') . '/.env'; file_put_contents($envPath, PHP_EOL . "SHOPWARE_CLI_API_TOKEN={$token->getToken()}", FILE_APPEND); $output->writeln("CLI API Token generated: {$token->getToken()}"); return Command::SUCCESS; }
- API调用示例:
curl -X GET "https://your-shopware-domain/api/product" \ -H "Authorization: Bearer ${SHOPWARE_CLI_API_TOKEN}" \ -H "Content-Type: application/json"
- 优缺点:
- 优点:利用Shopware原生机制,无需管理集成;令牌存储在环境变量中,安全性更高;CLI场景下更直观。
- 缺点:令牌过期需要重新生成;需确保用户权限配置正确,避免超权限访问。
方案3:系统级服务账户(适合长期后台任务)
对于需要长期运行的CLI任务,可创建系统级服务账户,与普通用户完全隔离:
- 实现步骤:
- 创建无后台登录权限的服务账户,仅分配API操作所需的最小权限。
- 生成永久令牌(或超长过期时间),存储在安全配置文件中(如
config/packages/cli_api.yaml),而非数据库。 - 在CLI命令中直接注入API客户端,使用服务账户的令牌进行调用。
- 代码示例(注入API客户端):
class CliApiCommand extends Command { private ApiClient $apiClient; public function __construct(ApiClientFactory $apiClientFactory) { parent::__construct(); $token = $this->container->getParameter('shopware.cli_api.token'); $this->apiClient = $apiClientFactory->createAuthenticatedClient($token); } protected function execute(InputInterface $input, OutputInterface $output): int { // 调用API $response = $this->apiClient->get('/api/product'); $products = json_decode($response->getContent(), true); $output->writeln("Found " . count($products['data']) . " products"); return Command::SUCCESS; } }
- 配置示例(config/packages/cli_api.yaml):
parameters: shopware.cli_api.token: '%env(SHOPWARE_CLI_API_TOKEN)%'
- 优缺点:
- 优点:账户权限完全独立,不影响普通用户;令牌存储在配置文件/环境变量中,安全性高;适合长期运行的后台任务。
- 缺点:需要额外配置参数,部署时需确保环境变量正确设置。
总结
- 若插件仅需临时使用API,选择方案1,自动化管理集成生命周期;
- 若为日常CLI脚本调用,选择方案2,利用原生令牌机制更便捷;
- 若为长期后台任务,选择方案3,系统级账户更安全稳定。
内容的提问来源于stack exchange,提问作者Grzegorz Jamróz
相关产品推荐
相关产品推荐

