Symfony 身份认证流程及事件
安装包列表
#创建空命令,控制器,表单类,安全类、测试等等
composer require --dev symfony/maker-bundle
#调试程序
composer require --dev symfony/profiler-pack
composer require symfonycasts/verify-email-bundle
composer require jms/serializer-bundle
#接口文档工具
composer require nelmio/api-doc-bundle
#NelmioApiDocBundle 依赖模板
composer require symfony/twig-bundle
composer require symfony/asset
创建用户 Entity
php bin/console 1make:user User
#更新数据库
php bin/console doctrine:schema:update --force
使用username作为唯一标识,邮箱和手机号作为补充字段,也可以作为登录认证字段。
在 App\Entity\User.php 增加字段
#[ORM\Column(type: 'datetime',nullable: true, options: [
"comment" => "最后一次登录日期"
])]
private ?\DateTime $lastLogin = null;
/**
* 邮箱不允许重复,通过逻辑验证重复
*/
#[ORM\Column( length: 30, unique: false, nullable: true )]
private ?string $email = null;
/**
* 手机号码不允许重复,通过逻辑验证重复
*/
#[ORM\Column(
length: 20,
unique: false,
nullable: true,
options: [
"comment" => "手机号"
]
)]
private ?string $phone = null;
设置Provider
security.yaml 设置自定义的数据对象 provider
security:
providers:
# used to reload user from session & other features (e.g. switch_user)
app_user_provider:
entity:
class: App\Entity\User
property: username
创建表单身份认证器
php bin/console make:auth
自动创建登录表单控制器,便于调试。
App\Security\FormUserAuthenticator
namespace App\Security;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Http\Authenticator\AbstractLoginFormAuthenticator;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\CsrfTokenBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials;
use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
use Symfony\Component\Security\Http\Util\TargetPathTrait;
/**
* 表单类型身份认证器
*/
class FormUserAuthenticator extends AbstractLoginFormAuthenticator
{
use TargetPathTrait;
public const LOGIN_ROUTE = 'app_login';
public function __construct(private UrlGeneratorInterface $urlGenerator)
{
}
public function authenticate(Request $request): Passport
{
$username = $request->request->get('username', '');
$request->getSession()->set(Security::LAST_USERNAME, $username);
return new Passport(
new UserBadge($username),
new PasswordCredentials($request->request->get('password', '')),
[
new CsrfTokenBadge('authenticate', $request->request->get('_csrf_token')),
]
);
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
{
if ($targetPath = $this->getTargetPath($request->getSession(), $firewallName)) {
return new RedirectResponse($targetPath);
}
// For example:
return new RedirectResponse($this->urlGenerator->generate('homepage'));
// throw new \Exception('TODO: provide a valid redirect inside '.__FILE__);
}
protected function getLoginUrl(Request $request): string
{
return $this->urlGenerator->generate(self::LOGIN_ROUTE);
}
}
LexikJWT 配置
security:
firewalls:
api_login:
pattern: ^/api/login
stateless: true
provider: app_user_provider
json_login:
username_path: username
password_path: password
check_path: /api/login_check
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
api:
pattern: ^/api
stateless: true
provider: app_user_provider
jwt: ~
main:
lazy: true
custom_authenticator: App\Security\FormUserAuthenticator
logout:
path: app_logout
provider: app_user_provider
access_control:
- { path: ^/api/login, roles: PUBLIC_ACCESS }
- { path: ^/api, roles: IS_AUTHENTICATED_FULLY }
基于表单的登录认证
基于JWT的登录认证
参考文章
[1] https://symfony.com/doc/current/security/custom_authenticator.html 自定义身份验证器
[2] https://symfony.com/bundles/LexikJWTAuthenticationBundle/current/index.html LexikJWTAuthentication安装文档
[3] https://symfony.com/doc/current/security.html#the-user 基于数据库的用户
[4] https://symfony.com/bundles/SymfonyMakerBundle/current/index.html MakerBundle
[5] https://symfony.com/doc/5.2/security/form_login_setup.html#generating-the-login-form 创建表单身份认证器及登录页