最主流稳定方式是集成LexikJWTAuthenticationBundle:三步完成——装包、生成RSA密钥对(或配HMAC secret)、配置security.yaml中login和api两个stateless防火墙并启用jwt: ~。

Symfony 中用 JWT 做认证,最主流、最稳定的方式是集成 LexikJWTAuthenticationBundle。它不是手动拼 Token 或写验证逻辑,而是把密钥管理、Token 生成、提取、解析、用户加载这些环节都封装好,直接对接 Symfony 安全系统。核心就三步:装包 → 生成密钥 → 配安全规则。
安装与初始化密钥
先用 Composer 安装:
composer require lexik/jwt-authentication-bundle
Bundle 会自动注册(Symfony 5.4+ 支持自动配置)。接着生成非对称密钥对(推荐 RSA):
php bin/console lexik:jwt:generate-keypair
命令会在 config/jwt/ 下创建 private.pem 和 public.pem。确保目录可写,且 Web 服务器能读取公钥。
如果想用 HMAC(更轻量,适合单服务场景),可跳过密钥生成,直接在配置里设 secret 字符串:
- 在
.env里加:JWT_SECRET=your-super-secret-hmac-key-here - 配置中改用:
secret_key: '%env(JWT_SECRET)%',并指定algorithm: HS256
配置安全防火墙
打开 config/packages/security.yaml,定义两个防火墙:
- 登录入口:开放给未认证用户,接收账号密码,返回 Token
-
API 主防火墙:拦截所有
/api/**请求,只认有效的 JWT
示例配置:
security:
enable_authenticator_manager: true
firewalls:
login:
pattern: ^/api/login
stateless: true
json_login:
check_path: /api/login_check
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
<pre class="brush:php;toolbar:false;">api:
pattern: ^/api
stateless: true
jwt: ~access_control:
- { path: ^/api/login, roles: PUBLIC_ACCESS }
- { path: ^/api, roles: IS_AUTHENTICATED_FULLY }
注意:
stateless: true是必须的,因为 JWT 认证不依赖 session;jwt: ~表示启用 Lexik 的 JWT 认证器。
Token 怎么传、怎么验
默认情况下,Bundle 从 Authorization: Bearer <token></token> 头里提取 Token。你也可以在 lexik_jwt_authentication.yaml 里扩展支持方式:
- 从 Cookie 读(比如前端存进
BEARERcookie) - 从 URL 查询参数(如
?bearer=xxx),仅限调试,不建议生产使用
验证过程全自动:收到请求 → 提取 Token → 用公钥(RSA)或 secret(HMAC)验签名 → 检查 exp、nbf 等声明 → 加载对应 User 对象 → 注入到 $this->getUser()。
自定义用户载荷和刷新机制
默认 Token 只含用户 ID(sub)和过期时间。如需额外字段(角色、权限、租户 ID),可实现 UserInterface::getRoles() 或监听 JWT_CREATED 事件注入 payload。
Token 过期后,通常需要刷新机制。Bundle 原生支持刷新(需开启 refresh_token_ttl 并配置刷新端点),但更常见做法是让前端在过期前主动调用 /api/token/refresh 换新 Token。
不复杂但容易忽略。











