{"id":1116,"date":"2025-06-12T13:20:46","date_gmt":"2025-06-12T05:20:46","guid":{"rendered":"https:\/\/www.zhaozhao123.cn\/php\/php-application-manual\/symfony\/1116.html"},"modified":"2025-06-12T13:20:46","modified_gmt":"2025-06-12T05:20:46","slug":"%e5%9c%a8symfony%e4%b8%ad%e5%ae%9e%e6%96%bd%e6%8e%88%e6%9d%83%ef%bc%9a%e5%bc%80%e5%8f%91%e8%80%85%e6%8c%87%e5%8d%97","status":"publish","type":"my1js","link":"https:\/\/www.zhaozhao123.cn\/php\/my1js\/1116.html","title":{"rendered":"\u5728Symfony\u4e2d\u5b9e\u65bd\u6388\u6743\uff1a\u5f00\u53d1\u8005\u6307\u5357"},"content":{"rendered":"<div class=\"wp-block-columns p-0 border is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\r\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\r\n<div class=\"wp-block-columns px-4 py-3 border-bottom has-background is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\" style=\"background:linear-gradient(243deg,rgb(238,238,238) 0%,rgba(58,166,242,0.15) 100%)\">\r\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\r\n<div class=\"wp-block-group is-nowrap is-layout-flex wp-container-core-group-is-layout-6c531013 wp-block-group-is-layout-flex\">\r\n<figure class=\"wp-block-image size-thumbnail is-resized is-style-rounded is-style-rounded--1\"><img decoding=\"async\" src=\"https:\/\/www.zhaozhao123.cn\/myitems\/images\/sites16\/2025\/06\/dyA-1-400x300.jpg\" alt=\"Bug&#32534;&#35793;&#29422;\" class=\"wp-image-1842\" style=\"object-fit:cover;width:30px;height:30px\"><\/figure>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading my-0\" style=\"font-size:clamp(0.875rem, 0.875rem + ((1vw - 0.2rem) * 0.175), 1rem);\">Bug&#32534;&#35793;&#29422;<\/h2>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n\r\n\r\n\r\n<div class=\"wp-block-columns px-xl-5 px-4 py-xl-4 py-3 is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\r\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\r\n<p>&#12298;&#22312;Symfony&#20013;&#23454;&#29616;&#25480;&#26435;&#65306;&#24320;&#21457;&#32773;&#25351;&#21335;&#12299;<\/p>\n<p>&#22312;&#29616;&#20195;Web&#24320;&#21457;&#20013;&#65292;&#23433;&#20840;&#24615;&#21644;&#26435;&#38480;&#25511;&#21046;&#26159;&#33267;&#20851;&#37325;&#35201;&#30340;&#12290;Symfony&#26694;&#26550;&#25552;&#20379;&#20102;&#24378;&#22823;&#30340;&#24037;&#20855;&#21644;&#27169;&#22359;&#26469;&#24110;&#21161;&#24320;&#21457;&#32773;&#36731;&#26494;&#22320;&#23454;&#29616;&#36825;&#20123;&#21151;&#33021;&#12290;&#20197;&#19979;&#26159;&#19968;&#20123;&#20851;&#38190;&#27493;&#39588;&#21644;&#26368;&#20339;&#23454;&#36341;&#65292;&#24110;&#21161;&#20320;&#22312;Symfony&#39033;&#30446;&#20013;&#23454;&#26045;&#25480;&#26435;&#12290;<\/p>\n<h3>1. &#23433;&#35013;&#24182;&#37197;&#32622;GuardBundle<\/h3>\n<p>&#39318;&#20808;&#65292;&#20320;&#38656;&#35201;&#23433;&#35013;<code>FOSUserBundle<\/code>&#21644;<code>FOSGuardBundle<\/code>&#65292;&#36825;&#26159;Symfony Security&#30340;&#19968;&#37096;&#20998;&#12290;<\/p>\n<pre><code class=\"language-bash\">composer require friendsofsymfony\/user-bundle fos\/guard-bundle<\/code><\/pre>\n<p>&#28982;&#21518;&#65292;&#37197;&#32622;&#36825;&#20004;&#20010;Bundle&#65306;<\/p>\n<h4><code>config\/bundles.php<\/code><\/h4>\n<pre><code class=\"language-php\">return [\n    \/\/ &#20854;&#20182;Bundle...\n\n    FOSUserBundleFOSUserBundle::class =&gt; ['all' =&gt; true],\n    FOSGuardBundleFOSGuardBundle::class =&gt; ['all' =&gt; true],\n];<\/code><\/pre>\n<h4><code>config\/packages\/security.yaml<\/code><\/h4>\n<pre><code class=\"language-yaml\">security:\n    encoders:\n        app_user: bcrypt\n\n    providers:\n        user_provider:\n            entity:\n                class: AppEntityUser\n                property: username\n\n    firewalls:\n        dev:\n            pattern: ^\/(_(dev|profiler|css|js)|assets)_\/\n            security: false\n\n        main:\n            anonymous: ~\n            guard:\n                authenticators:\n                    - AppSecurityAuthenticationFOSAuthenticator::class\n            logout:\n                path: \/logout\n            remember_me:\n                secret: 'your_secret_key'\n                lifetime: 604800 # 7 days in seconds\n                path: \/\n            form_login:\n                login_path: \/login\n                success_handler: AppControllerSecurityController::handleLoginSuccess\n                failure_handler: AppControllerSecurityController::handleLoginFailure\n                check_path: \/login_check\n                default_target_path: \/\n            logout_url: \/logout\n            access_control:\n                - { path: ^\/, roles: ROLE_USER }<\/code><\/pre>\n<h3>2. &#21019;&#24314;&#29992;&#25143;&#23454;&#20307;&#21644;&#35282;&#33394;<\/h3>\n<p>&#22312;<code>src\/Entity<\/code>&#30446;&#24405;&#19979;&#21019;&#24314;&#29992;&#25143;&#23454;&#20307;&#31867;&#65292;&#24182;&#23450;&#20041;&#35282;&#33394;&#65306;<\/p>\n<pre><code class=\"language-php\">\/\/ src\/Entity\/User.php\n\nuse DoctrineORMMapping as ORM;\nuse SymfonyComponentSecurityCoreUserUserInterface;\n\n\/**\n * @ORMEntity(repositoryClass=\"AppRepositoryUserRepository\")\n *\/\nclass User implements UserInterface\n{\n    \/**\n     * @ORMId\n     * @ORMGeneratedValue(strategy=\"AUTO\")\n     * @ORMColumn(type=\"integer\")\n     *\/\n    private $id;\n\n    \/**\n     * @ORMColumn(type=\"string\", length=180, unique=true)\n     *\/\n    private $username;\n\n    \/**\n     * @ORMColumn(type=\"string\", length=255)\n     *\/\n    private $email;\n\n    \/**\n     * @ORMColumn(type=\"boolean\")\n     *\/\n    private $enabled = true;\n\n    \/**\n     * @ORMColumn(type=\"json_array\")\n     *\/\n    private $roles = [];\n\n    \/\/ Getters and setters...\n}<\/code><\/pre>\n<h3>3. &#37197;&#32622;&#36335;&#30001;&#21644;&#25511;&#21046;&#22120;<\/h3>\n<p>&#21019;&#24314;&#30331;&#24405;&#21644;&#27880;&#38144;&#36335;&#30001;&#65292;&#24182;&#32534;&#20889;&#30456;&#24212;&#30340;&#25511;&#21046;&#22120;&#26469;&#22788;&#29702;&#36825;&#20123;&#35831;&#27714;&#65306;<\/p>\n<pre><code class=\"language-yaml\"># config\/routes.yaml\n\napp_login:\n    path: \/login\n    methods: [GET, POST]\n    controller: AppControllerSecurityController::loginAction\n\napp_logout:\n    path: \/logout\n    methods: [POST]<\/code><\/pre>\n<pre><code class=\"language-php\">\/\/ src\/Controller\/SecurityController.php\n\nnamespace AppController;\n\nuse SymfonyBundleFrameworkBundleControllerAbstractController;\nuse SymfonyComponentHttpFoundationRequest;\nuse SymfonyComponentRoutingAnnotationRoute;\nuse SymfonyComponentSecurityCoreEncoderUserPasswordEncoderInterface;\nuse SymfonyComponentSecurityCoreUserUserInterface;\nuse SymfonyComponentSecurityHttpAuthenticationTokenUsernamePasswordToken;\n\nclass SecurityController extends AbstractController\n{\n    private $passwordEncoder;\n\n    public function __construct(UserPasswordEncoderInterface $passwordEncoder)\n    {\n        $this-&gt;passwordEncoder = $passwordEncoder;\n    }\n\n    #[Route('\/login', name: 'app_login')]\n    public function loginAction(Request $request): Response\n    {\n        if ($this-&gt;isGranted('IS_AUTHENTICATED_FULLY')) {\n            return $this-&gt;redirectToRoute('target_route');\n        }\n\n        $authenticationUtils = $this-&gt;get('security.authentication_utils');\n\n        $error = $authenticationUtils-&gt;getLastAuthenticationError();\n        $lastUsername = $authenticationUtils-&gt;getLastUsername();\n\n        return $this-&gt;render('security\/login.html.twig', [\n            'last_username' =&gt; $lastUsername,\n            'error'         =&gt; $error,\n        ]);\n    }\n\n    #[Route('\/login_check', name: 'app_login_check')]\n    public function loginCheck(): void\n    {\n        throw new Exception('This is just a placeholder to prevent caching issues.');\n    }\n\n    #[Route('\/logout', name: 'app_logout')]\n    public function logoutAction(): void\n    {\n        \/\/ Perform any necessary actions before logging out\n        $this-&gt;authenticateUser(null);\n        $this-&gt;addFlash('notice', 'You have been logged out.');\n\n        return $this-&gt;redirectToRoute('homepage');\n    }\n\n    private function authenticateUser(?UserInterface $user): void\n    {\n        if (!$user) {\n            return;\n        }\n\n        $token = new UsernamePasswordToken($user, null, 'main', $user-&gt;getRoles());\n        $this-&gt;container-&gt;get('security.token_storage')-&gt;setToken($token);\n\n        if ($this-&gt;container-&gt;has('session')) {\n            $session = $this-&gt;container-&gt;get('session');\n            $session-&gt;set('_security_main', serialize($token));\n        }\n    }\n}<\/code><\/pre>\n<h3>4. &#23454;&#29616;&#35748;&#35777;&#36923;&#36753;<\/h3>\n<p>&#22312;<code>src\/Security\/Authentication\/FOSAuthenticator.php<\/code>&#20013;&#23454;&#29616;&#35748;&#35777;&#36923;&#36753;&#65306;<\/p>\n<pre><code class=\"language-php\">\/\/ src\/Security\/Authentication\/FOSAuthenticator.php\n\nnamespace AppSecurityAuthentication;\n\nuse FOSUserBundleModelUserInterface;\nuse SymfonyComponentHttpFoundationRequest;\nuse SymfonyComponentSecurityCoreAuthenticationSimpleFormAuthenticator;\nuse SymfonyComponentSecurityCoreExceptionAuthenticationException;\nuse SymfonyComponentSecurityCoreUserUserProviderInterface;\nuse SymfonyComponentHttpFoundationSessionSessionInterface;\n\nclass FOSAuthenticator extends SimpleFormAuthenticator\n{\n    private $userProvider;\n\n    public function __construct(UserProviderInterface $userProvider)\n    {\n        $this-&gt;userProvider = $userProvider;\n    }\n\n    protected function getCredentials(Request $request): array\n    {\n        return [\n            'username' =&gt; $request-&gt;get('username'),\n            'password' =&gt; $request-&gt;get('password'),\n        ];\n    }\n\n    protected function getUser($credentials, UserProviderInterface $userProvider): ?UserInterface\n    {\n        return $userProvider-&gt;loadUserByUsername($credentials['username']);\n    }\n\n    protected function checkCredentials($credentials, UserInterface $user): bool\n    {\n        return password_verify($credentials['password'], $user-&gt;getPassword());\n    }\n\n    protected function onAuthenticationSuccess(Request $request, UserInterface $user, string $firewallName): RedirectResponse\n    {\n        $session = $request-&gt;getSession();\n        if ($session !== null) {\n            $session-&gt;set('_security_' . $firewallName, serialize($this-&gt;createAuthenticatedToken($user, $firewallName)));\n        }\n\n        return new RedirectResponse($this-&gt;generateUrl('target_route'));\n    }\n\n    protected function onAuthenticationFailure(Request $request, AuthenticationException $exception): Response\n    {\n        return new RedirectResponse($this-&gt;generateUrl('app_login'), 302);\n    }\n\n    private function createAuthenticatedToken(UserInterface $user, string $firewallName): TokenInterface\n    {\n        $token = new UsernamePasswordToken($user, null, $firewallName, $user-&gt;getRoles());\n        $token-&gt;setAttributes(['authenticated' =&gt; true]);\n        return $token;\n    }\n}<\/code><\/pre>\n<h3>5. &#27979;&#35797;&#25480;&#26435;<\/h3>\n<p>&#26368;&#21518;&#65292;&#27979;&#35797;&#20320;&#30340;&#24212;&#29992;&#20197;&#30830;&#20445;&#25480;&#26435;&#21151;&#33021;&#27491;&#24120;&#24037;&#20316;&#12290;&#20320;&#21487;&#20197;&#36890;&#36807;&#35775;&#38382;&#19981;&#21516;&#30340;&#39029;&#38754;&#26469;&#39564;&#35777;&#29992;&#25143;&#26159;&#21542;&#33021;&#22815;&#35775;&#38382;&#21463;&#20445;&#25252;&#30340;&#20869;&#23481;&#12290;<\/p>\n<p>&#36890;&#36807;&#20197;&#19978;&#27493;&#39588;&#65292;&#20320;&#21487;&#20197;&#22312;Symfony&#39033;&#30446;&#20013;&#25104;&#21151;&#23454;&#29616;&#22522;&#26412;&#30340;&#25480;&#26435;&#21151;&#33021;&#12290;&#38543;&#30528;&#39033;&#30446;&#30340;&#25193;&#23637;&#65292;&#20320;&#36824;&#21487;&#20197;&#36827;&#19968;&#27493;&#25506;&#32034;&#26356;&#22810;&#30340;&#25480;&#26435;&#31574;&#30053;&#21644;&#21151;&#33021;&#65292;&#22914;&#35282;&#33394;&#32487;&#25215;&#12289;&#26435;&#38480;&#31649;&#29702;&#31561;&#12290;<\/p>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n<\/div><div class=\"wp-block-columns p-0 border is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\r\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\r\n<div class=\"wp-block-columns px-4 py-3 border-bottom has-background is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\" style=\"background:linear-gradient(243deg,rgb(238,238,238) 0%,rgba(58,166,242,0.15) 100%)\">\r\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\r\n<div class=\"wp-block-group is-nowrap is-layout-flex wp-container-core-group-is-layout-6c531013 wp-block-group-is-layout-flex\">\r\n<figure class=\"wp-block-image size-thumbnail is-resized is-style-rounded is-style-rounded--2\"><img decoding=\"async\" src=\"https:\/\/www.zhaozhao123.cn\/myitems\/images\/sites16\/2025\/06\/zp-400x300.jpg\" alt=\"&#40657;&#26495;Bug&#35762;&#24072;\" class=\"wp-image-1849\" style=\"object-fit:cover;width:30px;height:30px\"><\/figure>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading my-0\" style=\"font-size:clamp(0.875rem, 0.875rem + ((1vw - 0.2rem) * 0.175), 1rem);\">&#40657;&#26495;Bug&#35762;&#24072;<\/h2>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n\r\n\r\n\r\n<div class=\"wp-block-columns px-xl-5 px-4 py-xl-4 py-3 is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\r\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\r\n<body><h3>&#20171;&#32461;<\/h3><p>Symfony&#65292;&#19968;&#20010;&#24378;&#22823;&#30340;PHP&#26694;&#26550;&#65292;&#25552;&#20379;&#20102;&#19968;&#20010;&#20840;&#38754;&#30340;&#23433;&#20840;&#32452;&#20214;&#65292;&#20351;&#24471;&#24320;&#21457;&#32773;&#21487;&#20197;&#36731;&#26494;&#22788;&#29702;&#24212;&#29992;&#31243;&#24207;&#30340;&#36523;&#20221;&#39564;&#35777;&#21644;&#25480;&#26435;&#38382;&#39064;&#12290;&#22312;&#36825;&#31687;&#25991;&#31456;&#20013;&#65292;&#25105;&#20204;&#23558;&#35814;&#32454;&#20171;&#32461;&#22312;Symfony&#39033;&#30446;&#20013;&#23454;&#29616;&#26435;&#38480;&#25511;&#21046;&#30340;&#36807;&#31243;&#12290;&#25105;&#20204;&#23558;&#25506;&#35752;Symfony&#30340;&#25480;&#26435;&#31995;&#32479;&#65292;&#24182;&#25552;&#20379;&#23454;&#38469;&#20195;&#30721;&#31034;&#20363;&#20197;&#21152;&#28145;&#29702;&#35299;&#12290;<\/p><h3>&#29702;&#35299;Symfony Security<\/h3><p>Symfony &#23433;&#20840;&#32452;&#20214;&#20998;&#20026;&#20004;&#20010;&#20027;&#35201;&#37096;&#20998;&#65306;&#35748;&#35777;&#21644;&#25480;&#26435;&#12290;&#35748;&#35777;&#37096;&#20998;&#36127;&#36131;&#30830;&#35748;&#29992;&#25143;&#36523;&#20221;&#65292;&#32780;&#25480;&#26435;&#37096;&#20998;&#21017;&#25480;&#20104;&#24050;&#35748;&#35777;&#29992;&#25143;&#30340;&#26435;&#38480;&#12290;&#26412;&#25351;&#21335;&#23558;&#37325;&#28857;&#20171;&#32461;&#25480;&#26435;&#37096;&#20998;&#65292;&#20551;&#35774;&#29992;&#25143;&#24050;&#32463;&#36890;&#36807;&#35748;&#35777;&#12290;<\/p><p>Symfony&#30340;&#25480;&#26435;&#31995;&#32479;&#30340;&#26680;&#24515;&#32452;&#20214;&#21253;&#25324;&ldquo;&#25237;&#31080;&#32773;&rdquo;&#21644;&ldquo;&#35775;&#38382;&#20915;&#31574;&#31649;&#29702;&#32773;&rdquo;&#12290;&#25237;&#31080;&#32773;&#20915;&#23450;&#29992;&#25143;&#26159;&#21542;&#21487;&#20197;&#22312;&#36164;&#28304;&#19978;&#25191;&#34892;&#19968;&#20010;&#25805;&#20316;&#65292;&#32780;&#35775;&#38382;&#20915;&#31574;&#31649;&#29702;&#32773;&#21017;&#25910;&#38598;&#25237;&#31080;&#32773;&#30340;&#21709;&#24212;&#26469;&#20570;&#20986;&#26368;&#32456;&#30340;&#25480;&#26435;&#25511;&#21046;&#20915;&#31574;&#12290;<\/p><h3>&#37197;&#32622;&#35775;&#38382;&#25511;&#21046;<\/h3><p>&#23454;&#26045;&#25480;&#26435;&#30340;&#31532;&#19968;&#27493;&#26159;&#22312;&#35775;&#38382;&#25511;&#21046;&#26041;&#38754;&#36827;&#34892;&#37197;&#32622;&#12290;<code>security.yaml<\/code>&#25991;&#20214;&#12290;&#36825;&#26159;&#19968;&#20221;&#22522;&#26412;&#36335;&#32447;&#20445;&#25252;&#35268;&#21017;&#25163;&#20876;&#65292;&#31616;&#21333;&#26126;&#20102;&#12290;<\/p><pre><code>security:\n    access_control:\n        - { path: ^\/admin, roles: ROLE_ADMIN }\n        - { path: ^\/profile, roles: ROLE_USER }\n<\/code><\/pre><p>&#35813;&#37197;&#32622;&#22768;&#26126;&#20219;&#20309;&#20197;&#8230;&#24320;&#22836;&#30340;&#36335;&#30001;&#37117;&#36866;&#29992;&#12290;<code>\/admin<\/code>&#20165;&#23545;&#20855;&#26377;&ldquo;ROLE_ADMIN&rdquo;&#35282;&#33394;&#30340;&#29992;&#25143;&#24320;&#25918;&#65292;&#20197;&#21450;&#20197;&#26576;&#20123;&#21069;&#32512;&#24320;&#22987;&#30340;&#36335;&#30001;&#12290;<code>\/profile<\/code>&#35201;&#27714;&#29992;&#25143;&#20855;&#26377;&ldquo;ROLE_USER&rdquo;&#35282;&#33394;&#12290;<\/p><h3>&#21019;&#24314;&#36873;&#27665;<\/h3><p>&#20026;&#20102;&#36827;&#19968;&#27493;&#32454;&#21270;&#25480;&#26435;&#26816;&#26597;&#65292;&#25105;&#20204;&#38656;&#35201;&#21019;&#24314;&#36873;&#27665;&#12290;&#36873;&#27665;&#35753;&#24744;&#33021;&#22815;&#26681;&#25454;&#28041;&#21450;&#36164;&#28304;&#25110;&#23545;&#35937;&#30340;&#26356;&#22797;&#26434;&#30340;&#23433;&#20840;&#35268;&#21017;&#26469;&#20915;&#23450;&#12290;<\/p><pre><code>namespace AppSecurityVoter;\n\nuse SymfonyComponentSecurityCoreAuthorizationVoterVoter;\nuse SymfonyComponentSecurityCoreAuthenticationTokenTokenInterface;\n\nclass PostVoter extends Voter {\n    \/\/ Define your supported attributes and post instance check\n    protected function supports($attribute, $subject) {\n        if (!in_array($attribute, ['EDIT', 'DELETE'])) {\n            return false;\n        }\n\n        if (!$subject instanceof Post) {\n            return false;\n        }\n\n        return true;\n    }\n\n    \/\/ Voter logic implementation\n    protected function voteOnAttribute($attribute, $post, TokenInterface $token) {\n        $user = $token-&gt;getUser();\n\n        \/\/ Your custom logic to determine if the user can EDIT or DELETE the given Post instance\n        return $user === $post-&gt;getUser();\n    }\n}\n<\/code><\/pre><p>&#22312;&#23450;&#20041;&#20043;&#21518;&#65292;&#25105;&#20204;&#25509;&#19979;&#26469;&#20250;&#20570;&#20160;&#20040;&#65311;<code>supports<\/code>and<code>voteOnAttribute<\/code>&#22312;&#24744;&#30340;Voter&#31867;&#30340;&#26041;&#27861;&#20013;&#65292;&#24744;&#21487;&#20197;&#20687;&#20197;&#19979;&#26041;&#24335;&#22312;&#25511;&#21046;&#22120;&#25805;&#20316;&#20013;&#20351;&#29992;&#25480;&#26435;&#26816;&#26597;&#65306;<\/p><pre><code>public function editAction(Request $request, Post $post) {\n    $this-&gt;denyAccessUnlessGranted('EDIT', $post);\n\n    \/\/ ... edit post\n}\n<\/code><\/pre><p>&#36825;&#12290;<code>denyAccessUnlessGranted<\/code>&#35813;&#26041;&#27861;&#23558;&#19982;&#25237;&#31080;&#32773;&#36827;&#34892;&#20132;&#20114;&#65292;&#20197;&#30830;&#20445;&#24403;&#21069;&#29992;&#25143;&#26377;&#26435;&#32534;&#36753;&#24086;&#23376;&#12290;<\/p><h3>&#35282;&#33394;&#23618;&#32423;&#20307;&#31995;<\/h3><p>Symfony &#25552;&#20379;&#20102;&#19968;&#31181;&#31616;&#21333;&#30340;&#26041;&#27861;&#26469;&#23450;&#20041;&#24744;&#30340;&#35282;&#33394;&#23618;&#27425;&#32467;&#26500;&#12290;<code>security.yaml<\/code>&#36825;&#31181;&#23618;&#32423;&#32467;&#26500;&#20801;&#35768;&#26576;&#20123;&#35282;&#33394;&#33258;&#21160;&#25317;&#26377;&#20854;&#20182;&#35282;&#33394;&#30340;&#25152;&#26377;&#26435;&#38480;&#12290;<\/p><pre><code>security:\n    role_hierarchy:\n        ROLE_ADMIN: ROLE_USER\n        ROLE_SUPER_ADMIN: ROLE_ADMIN\n<\/code><\/pre><p>&#36825;&#24847;&#21619;&#30528;&#25317;&#26377;&ldquo;ROLE_SUPER_ADMIN&rdquo;&#35282;&#33394;&#30340;&#29992;&#25143;&#23558;&#33258;&#21160;&#33719;&#24471;&ldquo;ROLE_ADMIN&rdquo;&#21644;&ldquo;ROLE_USER&rdquo;&#30340;&#26435;&#38480;&#12290;<\/p><h3>&#20445;&#25252;&#26381;&#21153;<\/h3><p>&#38500;&#20102;&#22312;&#25511;&#21046;&#22120;&#19978;&#25511;&#21046;&#35775;&#38382;&#65292;&#36824;&#21487;&#20197;&#36890;&#36807;&#20351;&#29992;&#23433;&#20840;&#34920;&#36798;&#24335;&#26469;&#30452;&#25509;&#23450;&#20041;&#26381;&#21153;&#30340;&#23433;&#20840;&#38480;&#21046;&#12290;<\/p><pre><code>services:\n    AppServiceAdminService:\n        \/\/ ... other configurations ...\n        arguments:\n            - '@security.authorization_checker'\n<\/code><\/pre><p>&#28982;&#21518;&#65292;&#22312;&#26381;&#21153;&#31867;&#20013;&#65292;&#20320;&#21487;&#20197;&#35843;&#29992;&#12290;<code>isGranted<\/code>&#22312;&#25191;&#34892;&#25935;&#24863;&#25805;&#20316;&#20043;&#21069;&#65292;&#26816;&#26597;&#29992;&#25143;&#26159;&#21542;&#26377;&#36866;&#24403;&#30340;&#26435;&#38480;&#30340;&#26041;&#27861;&#12290;<\/p><pre><code>use SymfonyComponentSecurityCoreAuthorizationAuthorizationCheckerInterface;\n\nclass AdminService {\n    private $authorizationChecker;\n\n    public function __construct(AuthorizationCheckerInterface $authorizationChecker) {\n        $this-&gt;authorizationChecker = $authorizationChecker;\n    }\n\n    public function sensitiveAction() {\n        if (!$this-&gt;authorizationChecker-&gt;isGranted('ROLE_ADMIN')) {\n            throw new Exception('Access Denied.');\n        }\n\n        \/\/ Perform sensitive action\n    }\n}\n<\/code><\/pre><p>&#22240;&#27492;&#65292;Symfony &#30340;&#24378;&#22823;&#23433;&#20840;&#31995;&#32479;&#32467;&#21512;&#20102;&#25237;&#31080;&#32773;&#21644;&#35775;&#38382;&#25511;&#21046;&#35268;&#21017;&#65292;&#20026;&#24320;&#21457;&#32773;&#25552;&#20379;&#20102;&#23454;&#26045;&#26377;&#25928;&#19988;&#32454;&#33268;&#30340;&#35775;&#38382;&#31649;&#29702;&#25152;&#38656;&#30340;&#24037;&#20855;&#12290;<\/p><h3>&#26368;&#21518;&#30340;&#35805;<\/h3><p>&#22522;&#20110;&#36825;&#20010;&#22522;&#30784;&#65292;&#20320;&#24212;&#35813;&#29616;&#22312;&#33021;&#22815;&#24212;&#23545;Symfony&#20013;&#30340;&#31616;&#21333;&#21644;&#22797;&#26434;&#30340;&#25480;&#26435;&#26041;&#26696;&#12290;&#35760;&#20303;&#26368;&#20339;&#30340;&#23433;&#20840;&#23454;&#36341;&#21253;&#25324;&#37197;&#32622;&#33391;&#22909;&#30340;&#31995;&#32479;&#21644;&#35880;&#24910;&#30340;&#32534;&#30721;&#20064;&#24815;&#12290;&#22987;&#32456;&#36827;&#34892;&#23450;&#26399;&#30340;&#23433;&#20840;&#23457;&#35745;&#65292;&#24182;&#19988;&#22312;&#24443;&#24213;&#27979;&#35797;&#21518;&#19981;&#35201;&#20551;&#35774;&#24744;&#30340;&#31995;&#32479;&#26159;&#23433;&#20840;&#30340;&#65281;<\/p><\/body>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n<\/div><div class=\"wp-block-columns p-0 border is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\r\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\r\n<div class=\"wp-block-columns px-4 py-3 border-bottom has-background is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\" style=\"background:linear-gradient(243deg,rgb(238,238,238) 0%,rgba(58,166,242,0.15) 100%)\">\r\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\r\n<div class=\"wp-block-group is-nowrap is-layout-flex wp-container-core-group-is-layout-6c531013 wp-block-group-is-layout-flex\">\r\n<figure class=\"wp-block-image size-thumbnail is-resized is-style-rounded is-style-rounded--3\"><img decoding=\"async\" src=\"https:\/\/www.zhaozhao123.cn\/myitems\/images\/sites16\/2025\/06\/xygcfznnzczhsdmwydzhsmzzzmddnq-400x300.jpg\" alt=\"&#38271;&#24037;&#30721;&#22900;1523\" class=\"wp-image-2906\" style=\"object-fit:cover;width:30px;height:30px\"><\/figure>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading my-0\" style=\"font-size:clamp(0.875rem, 0.875rem + ((1vw - 0.2rem) * 0.175), 1rem);\">&#38271;&#24037;&#30721;&#22900;1523<\/h2>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n\r\n\r\n\r\n<div class=\"wp-block-columns px-xl-5 px-4 py-xl-4 py-3 is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\r\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\r\n<p>&#22312; Symfony &#20013;&#23454;&#29616;&#25480;&#26435;&#21151;&#33021;&#26159;&#19968;&#39033;&#37325;&#35201;&#30340;&#20219;&#21153;&#65292;&#36825;&#19981;&#20165;&#26377;&#21161;&#20110;&#20445;&#25252;&#24212;&#29992;&#30340;&#23433;&#20840;&#24615;&#65292;&#36824;&#33021;&#25552;&#21319;&#29992;&#25143;&#20307;&#39564;&#12290;&#20197;&#19979;&#26159;&#19968;&#20123;&#22522;&#26412;&#30340;&#27493;&#39588;&#21644;&#24314;&#35758;&#65306;<\/p>\n<h3>1. &#23433;&#35013;&#24182;&#37197;&#32622; <code>security.yml<\/code> &#25991;&#20214;<\/h3>\n<p>&#39318;&#20808;&#65292;&#20320;&#38656;&#35201;&#21019;&#24314;&#19968;&#20010; <code>security.yml<\/code> &#25991;&#20214;&#26469;&#23450;&#20041;&#36523;&#20221;&#39564;&#35777;&#21644;&#25480;&#26435;&#31574;&#30053;&#12290;<\/p>\n<pre><code class=\"language-yaml\"># security.yml\nsecurity:\n    # ...\n    providers:\n        - class: AppSecurityCustomUserProvider\n          options:\n              email_field: 'email'\n              password_field: 'password'\n\n    firewalls:\n        - id: default\n          pattern: ^\/\n          form_login:\n              login_path: \/login\n              check_path: \/login_check\n          logout:\n              path:   \/logout\n              target: \/\n          anonymous: ~\n\n        - id: auth\n          pattern: ^\/api\/auth\n          form_login:\n              login_path: \/login\n              check_path: \/login_check\n          logout:\n              path:   \/logout\n              target: \/\n          anonymous: false\n\n    access_control:\n        - { path: ^\/api, roles: IS_AUTHENTICATED_ANONYMOUSLY }<\/code><\/pre>\n<h3>2. &#21019;&#24314;&#33258;&#23450;&#20041;&#29992;&#25143;&#25552;&#20379;&#21830;<\/h3>\n<p>&#22312; Symfony &#20013;&#65292;&#20320;&#21487;&#20197;&#20351;&#29992; <code>AppSecurityCustomUserProvider<\/code> &#26469;&#23454;&#29616;&#33258;&#23450;&#20041;&#29992;&#25143;&#39564;&#35777;&#31574;&#30053;&#12290;&#36825;&#20010;&#31867;&#20250;&#22788;&#29702;&#29992;&#25143;&#30340;&#30331;&#24405;&#21644;&#35748;&#35777;&#36807;&#31243;&#65292;&#24182;&#23558;&#25968;&#25454;&#23384;&#20648;&#21040;&#25968;&#25454;&#24211;&#25110;&#20854;&#20182;&#25345;&#20037;&#21270;&#23384;&#20648;&#20013;&#12290;<\/p>\n<pre><code class=\"language-php\">&lt;?php\n\nnamespace AppSecurity;\n\nuse SymfonyComponentSecurityCoreUserUserInterface;\nuse SymfonyComponentSecurityCoreUserUserProviderInterface;\nuse SymfonyComponentSecurityCoreExceptionUsernameNotFoundException;\nuse SymfonyComponentSecurityCoreExceptionBadCredentialsException;\n\nclass CustomUserProvider implements UserProviderInterface\n{\n    public function loadUserByUsername($username)\n    {\n        \/\/ &#22312;&#36825;&#37324;&#23454;&#29616;&#36923;&#36753;&#65292;&#20363;&#22914;&#26816;&#26597;&#29992;&#25143;&#21517;&#26159;&#21542;&#23384;&#22312;&#65292;&#23494;&#30721;&#26159;&#21542;&#27491;&#30830;&#31561;&#12290;\n        \/\/ &#36825;&#37324;&#20551;&#35774;&#26377;&#19968;&#20010;&#26041;&#27861;&#21487;&#20197;&#33719;&#21462;&#29992;&#25143;&#20449;&#24687;&#12290;\n        $userRepository = new UserRepository();\n        $user = $userRepository-&gt;findByEmail($username);\n\n        if (!$user) {\n            throw new UsernameNotFoundException('User not found');\n        }\n\n        return $user;\n    }\n\n    public function supportsClass($class)\n    {\n        return $class === AppEntityUser::class;\n    }\n}<\/code><\/pre>\n<h3>3. &#23454;&#29616;&#36523;&#20221;&#39564;&#35777;&#19982;&#25480;&#26435;&#35268;&#21017;<\/h3>\n<p>&#25509;&#19979;&#26469;&#65292;&#38656;&#35201;&#26681;&#25454;&#19994;&#21153;&#38656;&#27714;&#35774;&#32622;&#36523;&#20221;&#39564;&#35777;&#21644;&#25480;&#26435;&#35268;&#21017;&#12290;&#36825;&#36890;&#24120;&#28041;&#21450;&#21040;&#35774;&#32622;&#36335;&#30001;&#26435;&#38480;&#21644;&#25511;&#21046;&#35775;&#38382;&#12290;<\/p>\n<pre><code class=\"language-yaml\"># routes.yaml\nrouter:\n    resources:\n        - :api\n        - :auth<\/code><\/pre>\n<p>&#22312;&#36825;&#20123;&#36335;&#30001;&#19978;&#65292;&#21487;&#20197;&#26681;&#25454;&#38656;&#35201;&#28155;&#21152;&#19981;&#21516;&#30340;&#26435;&#38480;&#25511;&#21046;&#12290;<\/p>\n<pre><code class=\"language-yaml\"># api.yaml\napi:\n    security:\n        access_control:\n            - { path: ^\/api\/auth, roles: IS_AUTHENTICATED_ANONYMOUSLY }<\/code><\/pre>\n<h3>4. &#20351;&#29992; <code>@SecurityGuard<\/code> &#27880;&#35299;<\/h3>\n<p>&#20026;&#20102;&#30830;&#20445;&#29992;&#25143;&#36890;&#36807;&#20102;&#23433;&#20840;&#39564;&#35777;&#65292;&#21487;&#20197;&#22312;&#25511;&#21046;&#22120;&#20013;&#28155;&#21152; <code>@SecurityGuard<\/code> &#27880;&#35299;&#26469;&#35302;&#21457;&#23433;&#20840;&#26816;&#26597;&#12290;<\/p>\n<pre><code class=\"language-php\">&lt;?php\n\nnamespace AppController;\n\nuse SymfonyBundleFrameworkBundleControllerAbstractController;\nuse SymfonyComponentHttpFoundationResponse;\nuse SymfonyComponentRoutingAnnotationRoute;\n\nclass AuthController extends AbstractController\n{\n    \/**\n     * @Route(\"\/api\/auth\", name=\"api_auth\")\n     *\/\n    public function authenticate(): Response\n    {\n        \/\/ &#26816;&#26597;&#29992;&#25143;&#26159;&#21542;&#24050;&#30331;&#24405;\n        if ($this-&gt;isGranted(\"IS_AUTHENTICATED_ANONYMOUSLY\")) {\n            return new Response(\"You are already authenticated as an anonymous user.\");\n        } else {\n            \/\/ &#22914;&#26524;&#19981;&#26159;&#21311;&#21517;&#29992;&#25143;&#65292;&#21017;&#36339;&#36716;&#33267;&#30331;&#24405;&#39029;&#38754;\n            return $this-&gt;redirectToRoute(\"app_login\");\n        }\n    }\n}<\/code><\/pre>\n<h3>&#31034;&#20363;&#20195;&#30721;<\/h3>\n<p>&#20197;&#19979;&#26159;&#19968;&#20010;&#31616;&#21333;&#30340;&#31034;&#20363;&#20195;&#30721;&#29255;&#27573;&#65292;&#23637;&#31034;&#20102;&#22914;&#20309;&#22312; Symfony &#24212;&#29992;&#31243;&#24207;&#20013;&#20351;&#29992;&#33258;&#23450;&#20041;&#29992;&#25143;&#39564;&#35777;&#31574;&#30053;&#65306;<\/p>\n<pre><code class=\"language-php\">&lt;?php\n\nnamespace AppSecurity;\n\nuse SymfonyComponentSecurityCoreUserUserInterface;\nuse SymfonyComponentSecurityCoreUserUserProviderInterface;\nuse SymfonyComponentSecurityCoreExceptionUsernameNotFoundException;\nuse SymfonyComponentSecurityCoreExceptionBadCredentialsException;\n\nclass CustomUserProvider implements UserProviderInterface\n{\n    private $userRepository;\n\n    public function __construct(UserRepository $userRepository)\n    {\n        $this-&gt;userRepository = $userRepository;\n    }\n\n    public function loadUserByUsername($username)\n    {\n        $user = $this-&gt;userRepository-&gt;findOneBy(['email' =&gt; $username]);\n\n        if (!$user) {\n            throw new UsernameNotFoundException('User not found');\n        }\n\n        return $user;\n    }\n\n    public function supportsClass($class)\n    {\n        return $class === AppEntityUser::class;\n    }\n}<\/code><\/pre>\n<h3>&#24635;&#32467;<\/h3>\n<p>&#36890;&#36807;&#20197;&#19978;&#27493;&#39588;&#65292;&#20320;&#21487;&#20197;&#20026; Symfony &#24212;&#29992;&#31243;&#24207;&#20013;&#30340;&#36164;&#28304;&#25552;&#20379;&#36523;&#20221;&#39564;&#35777;&#21644;&#25480;&#26435;&#26381;&#21153;&#12290;&#27880;&#24847;&#65292;&#23454;&#38469;&#24212;&#29992;&#20013;&#36824;&#38656;&#35201;&#32771;&#34385;&#26356;&#22797;&#26434;&#30340;&#24773;&#20917;&#65292;&#22914;&#32531;&#23384;&#26426;&#21046;&#12289;&#29992;&#25143;&#31649;&#29702;&#12289;&#38169;&#35823;&#22788;&#29702;&#31561;&#12290;&#24076;&#26395;&#36825;&#33021;&#24110;&#21161;&#20320;&#22312; Symfony &#24320;&#21457;&#36807;&#31243;&#20013;&#23454;&#29616;&#26377;&#25928;&#30340;&#36523;&#20221;&#39564;&#35777;&#21644;&#25480;&#26435;&#35299;&#20915;&#26041;&#26696;&#12290;<\/p>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Bug&#32534;&#35793;&#29422; &#12298;&#22312;Symfony&#20013;&#23454;&#29616;&#25480;&#26435;&#65306;&#24320;&#21457;&#32773;&#25351;&#21335;&#12299; &#22312;&#038;#29..<\/p>\n","protected":false},"author":1,"featured_media":0,"menu_order":0,"template":"","meta":{"_acf_changed":false},"tags":[],"my1js2nav":[45],"tuisongtax":[],"class_list":["post-1116","my1js","type-my1js","status-publish","hentry","my1js2nav-symfony"],"acf":{"qian_art_seotitle":"","qian_art_seotitle_source":{"label":"SEO\u6807\u9898","type":"text","formatted_value":""},"qian_art_seokws":"","qian_art_seokws_source":{"label":"SEO\u5173\u952e\u8bcd","type":"text","formatted_value":""},"qian_art_stzhong":"","qian_art_stzhong_source":{"label":"\u4e2d | \u77ed\u6807\u9898","type":"text","formatted_value":""}},"_links":{"self":[{"href":"https:\/\/www.zhaozhao123.cn\/php\/wp-json\/wp\/v2\/my1js\/1116","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.zhaozhao123.cn\/php\/wp-json\/wp\/v2\/my1js"}],"about":[{"href":"https:\/\/www.zhaozhao123.cn\/php\/wp-json\/wp\/v2\/types\/my1js"}],"author":[{"embeddable":true,"href":"https:\/\/www.zhaozhao123.cn\/php\/wp-json\/wp\/v2\/users\/1"}],"wp:attachment":[{"href":"https:\/\/www.zhaozhao123.cn\/php\/wp-json\/wp\/v2\/media?parent=1116"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.zhaozhao123.cn\/php\/wp-json\/wp\/v2\/tags?post=1116"},{"taxonomy":"my1js2nav","embeddable":true,"href":"https:\/\/www.zhaozhao123.cn\/php\/wp-json\/wp\/v2\/my1js2nav?post=1116"},{"taxonomy":"tuisongtax","embeddable":true,"href":"https:\/\/www.zhaozhao123.cn\/php\/wp-json\/wp\/v2\/tuisongtax?post=1116"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}