Nelmio API Doc 3.4配置Swagger API-Key鉴权:校验逻辑位置咨询
配置API密钥存储与校验逻辑的实现步骤
首先得明确:Nelmio API Doc只是用来生成Swagger文档的工具,实际的密钥校验逻辑需要你在Symfony项目中自行实现,Nelmio的配置只负责展示文档层面的授权规则。下面一步步帮你搞定:
1. 安全存储你的API密钥
绝对不要把密钥硬编码到代码里,推荐用环境变量存储:
- 在项目根目录的
.env文件中添加(开发环境):
APP_API_KEY=abc123
- 生产环境请通过服务器的环境变量配置(比如Nginx、Apache的环境变量设置,或者Docker的环境变量),避免密钥被提交到版本控制。
2. 实现API密钥的校验逻辑
这里提供两种常用的实现方式,按需选择:
方式一:用事件监听器(简单直接,适合小型项目)
创建一个请求监听器,在请求到达控制器前校验Header里的Authorization值:
// src/EventListener/ApiKeyListener.php namespace App\EventListener; use Symfony\Component\HttpKernel\Event\RequestEvent; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; class ApiKeyListener { private $parameterBag; public function __construct(ParameterBagInterface $parameterBag) { $this->parameterBag = $parameterBag; } public function onKernelRequest(RequestEvent $event) { // 只校验API前缀的路由,避免影响非API请求 $request = $event->getRequest(); if (strpos($request->getPathInfo(), '/api') !== 0) { return; } $requestApiKey = $request->headers->get('Authorization'); $validApiKey = $this->parameterBag->get('app_api_key'); // 校验密钥是否存在且匹配 if (!$requestApiKey || $requestApiKey !== $validApiKey) { $response = new Response('无效或缺失API密钥', Response::HTTP_UNAUTHORIZED); $event->setResponse($response); } } }
然后在services.yaml中注册这个监听器:
# config/services.yaml services: App\EventListener\ApiKeyListener: arguments: $parameterBag: '@parameter_bag' tags: - { name: kernel.event_listener, event: kernel.request }
方式二:用Symfony Security认证器(规范严谨,适合复杂权限场景)
如果你的项目用了Symfony Security组件,推荐用自定义认证器来处理:
// src/Security/ApiKeyAuthenticator.php namespace App\Security; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Security\Core\Exception\AuthenticationException; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Http\Authenticator\AbstractAuthenticator; use Symfony\Component\Security\Http\Authenticator\Passport\Passport; use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge; use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; class ApiKeyAuthenticator extends AbstractAuthenticator { private $parameterBag; public function __construct(ParameterBagInterface $parameterBag) { $this->parameterBag = $parameterBag; } public function supports(Request $request): ?bool { // 仅对API路由生效 return strpos($request->getPathInfo(), '/api') === 0 && $request->headers->has('Authorization'); } public function authenticate(Request $request): Passport { $requestApiKey = $request->headers->get('Authorization'); $validApiKey = $this->parameterBag->get('app_api_key'); if ($requestApiKey !== $validApiKey) { throw new AuthenticationException('无效的API密钥'); } // 这里可以关联系统用户,不需要的话用匿名用户标识即可 return new SelfValidatingPassport(new UserBadge('api-authenticated-user')); } public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response { // 认证成功,继续执行控制器逻辑 return null; } public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response { $responseData = [ 'message' => strtr($exception->getMessageKey(), $exception->getMessageData()) ]; return new Response(json_encode($responseData), Response::HTTP_UNAUTHORIZED, ['Content-Type' => 'application/json']); } }
接着在security.yaml中配置防火墙:
# config/packages/security.yaml security: enable_authenticator_manager: true firewalls: api: pattern: ^/api stateless: true custom_authenticators: - App\Security\ApiKeyAuthenticator
3. Swagger文档的优化(可选)
你已经完成了Swagger的授权规则配置,如果想让Swagger UI默认填充测试用的密钥(仅开发环境使用),可以在nelmio_api_doc.yaml中添加:
# config/packages/nelmio_api_doc.yaml nelmio_api_doc: documentation: schemes: [https] securityDefinitions: app_api_key: type: apiKey description: 'App Api Key' name: Authorization in: header security: - app_api_key: [] # 开发环境下让Swagger UI默认填充密钥,生产环境请删除这部分 swagger: api_keys: app_api_key: 'abc123'
注意:这里的默认值只是方便测试,实际校验还是依赖你前面实现的逻辑,生产环境绝对不要配置这个,避免密钥泄露。
内容的提问来源于stack exchange,提问作者Zwen2012
相关产品推荐
相关产品推荐

