请教如何实现Symfony 5登录表单的JWT身份认证功能
在Symfony 5中实现带JWT身份认证的登录表单
1. 安装依赖
首先安装JWT认证 bundle 和 Symfony安全组件:
composer require lexik/jwt-authentication-bundle symfony/security-bundle
2. 生成JWT密钥对
执行命令生成加密用的公私钥:
php bin/console lexik:jwt:generate-keypair
密钥会自动生成在config/jwt/目录下,注意妥善保管私钥。
3. 配置JWT Bundle
修改config/packages/lexik_jwt_authentication.yaml,添加基础配置:
lexik_jwt_authentication: secret_key: '%env(resolve:JWT_SECRET_KEY)%' public_key: '%env(resolve:JWT_PUBLIC_KEY)%' pass_phrase: '%env(JWT_PASSPHRASE)%' token_ttl: 3600 # 令牌有效期,单位秒
同时在.env文件中配置环境变量:
JWT_SECRET_KEY=%kernel.project_dir%/config/jwt/private.pem JWT_PUBLIC_KEY=%kernel.project_dir%/config/jwt/public.pem JWT_PASSPHRASE=your_custom_passphrase # 替换成你自己的密码
4. 配置安全认证规则
编辑config/packages/security.yaml,设置防火墙和访问控制:
security: encoders: App\Entity\User: algorithm: auto # 自动匹配用户密码的加密算法 providers: app_user_provider: entity: class: App\Entity\User # 替换成你的用户实体类 property: email # 用邮箱作为登录标识 firewalls: dev: pattern: ^/(_(profiler|wdt)|css|images|js)/ security: false main: stateless: true # JWT认证是无状态的 anonymous: true # 允许匿名访问登录接口 json_login: check_path: /api/login_check # 登录校验路径 success_handler: lexik_jwt_authentication.handler.authentication_success failure_handler: lexik_jwt_authentication.handler.authentication_failure jwt: ~ # 启用JWT认证 access_control: - { path: ^/api/login_check, roles: IS_AUTHENTICATED_ANONYMOUSLY } # 登录接口允许匿名访问 - { path: ^/api, roles: IS_AUTHENTICATED_FULLY } # 其他API接口需要完整认证
5. 配置登录路由
在config/routes.yaml中添加登录校验的路由:
api_login_check: path: /api/login_check
6. 创建登录表单(可选)
如果需要用Symfony表单组件构建登录页面,创建LoginFormType:
// src/Form/LoginFormType.php namespace App\Form; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\Extension\Core\Type\EmailType; use Symfony\Component\Form\Extension\Core\Type\PasswordType; use Symfony\Component\OptionsResolver\OptionsResolver; class LoginFormType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('email', EmailType::class) ->add('password', PasswordType::class); } public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ 'csrf_protection' => false, // JWT登录不需要CSRF 'data_class' => null, ]); } }
之后可以在控制器中渲染表单,让用户提交数据到/api/login_check(注意表单提交方式为POST,且Content-Type需为application/json)。
7. 测试登录
使用curl命令测试登录接口:
curl -X POST -H "Content-Type: application/json" http://your-domain/api/login_check -d '{"email":"user@example.com","password":"your_password"}'
成功后会返回包含JWT令牌的JSON响应:
{"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9..."}
8. 访问受保护路由
在请求头中携带JWT令牌访问受保护的API接口:
curl -H "Authorization: Bearer your_jwt_token" http://your-domain/api/protected-resource
内容的提问来源于stack exchange,提问作者Serge Alain
相关产品推荐
相关产品推荐

