Silex 2:区域设置的安全防火墙错误 (Silex SecurityServiceProvider + PmaxsLocaleServiceProvider)

2022-01-16 00:00:00 frameworks php symfony silex

我看到了这个解决方案,但我无法让它工作......

I saw this solution but I can't make it works...

这是我的代码,我尝试了什么,得到了什么:

So here is my code, what I tried and what I get :

1/我的安全提供商:

$app->register(new SilexProviderSessionServiceProvider());
$app->register(new SilexProviderSecurityServiceProvider(), array(
    'security.firewalls' => array(
        'secured' => array(
            'pattern' => '^/',
            'anonymous' => true,
            'logout' => true,
            'form' => array(
                'login_path' => '/login',
                'check_path' => '/login_check'),
            'users' => function () use ($app) {
                return new MyappDAOUserDAO($app['db']);
            },
        ),
    ),
));

2/我的翻译提供商

我使用:https://github.com/pmaxs/silex-locale

$app->register(new SilexProviderTranslationServiceProvider());
$app->register(new PmaxsSilexLocaleProviderLocaleServiceProvider(), [
    'locale.locales' => ['en', 'fr'],
    'locale.default_locale' => 'en',
    'locale.resolve_by_host' => false,
    'locale.exclude_routes' => ['^_']
]);
$app->register(new SilexProviderLocaleServiceProvider());

$app->extend('translator', function($translator, $app) {
    $translator->addLoader('yaml', new YamlFileLoader());
    // The translation file : one by langage, add new here
    $translator->addResource('yaml', __DIR__.'/../src/locales/en.yml', 'en');
    $translator->addResource('yaml', __DIR__.'/../src/locales/fr.yml', 'fr');

    return $translator;
});

这样我的路线没有 /{_locale}/ 但当我有 /my-path, /locale/my-path.

This way my route have no /{_locale}/ but still works when I have /my-path, /locale/my-path.

3/我的登录控制器

$app->get('/login', function(Request $request) use ($app) {
    return $app['twig']->render('login.html.twig', array(
        'error'         => $app['security.last_error']($request),
        'last_username' => $app['session']->get('_security.last_username'),
    ));
})->bind('login');

我尝试了什么 - 我得到的错误

  • 当我的 URL 是 /login 时,它可以工作:我回到连接的主页.
  • 当我的 URL 是 /fr/login 时,它不起作用:我的 URL 变成 /fr/login_check 并向我发送 error 404(这是正常的,因为我没有此 URL 的视图/页面,但不知道为什么它会尝试显示此页面并且不像以前那样连接我).
  • What I tried - The error I get

    • When my URL is /login it works : I came back to my Home page connected.
    • When my URL is /fr/login it doesn't work : my URL became /fr/login_check and send me a error 404 (this is normal because I have no view / page for this URL but no idea why it tries to display this page and don't connect me as before).
    • 所以我尝试在我的安全提供程序中更改它:

      So I tried to change this in my Security Provider:

       'form' => array(
           'login_path' => '/login',
           'check_path' => '/{_locale}/login_check'),
      

      它给了我一个 error 500 :在呈现模板期间引发了异常(无法为命名路由login_check"生成 URL,因为这样的路由不存在.").

      所以我回到我的其他安全提供程序(没有 /{_locale}/)并按照我看到的解决方案中的建议更改我的登录控制器:

      So I came back to my other Security Provider (without the /{_locale}/) and change my login controller as suggested in the solution I saw :

      $app->get('/{_locale}/login', function(Request $request) use ($app) {
          return $app['twig']->render('login.html.twig', array(
              'error'         => $app['security.last_error']($request),
              'last_username' => $app['session']->get('_security.last_username'),
          ));
      })->bind('login');
      

      • 现在,当我尝试使用我的默认语言环境 (en) 登录时,我有这个 URL /en/login 并且它可以工作.
      • 当我尝试更改法语的语言时,我有这个 URL /fr/en/login 可以登录,然后我又回到了我在 URL 上的 error 404/fr/login_check.
        • Now when I try to log with my default locale (en), I have this URL /en/login and it works.
        • When I try to change langage for French I have this URL /fr/en/login to login and I came back to my error 404 on URL /fr/login_check.
        • 当我尝试从 /fr/my-page 使用 URL /fr/logouterror 404 注销时遇到同样的问题>...

          I have the same problem when I try to LOGOUT from /fr/my-page with a error 404 on URL /fr/logout...

          有什么想法可以让 Silex 安全提供程序与 pmaxs/silex-locale 一起工作?

          Any idea to make the Silex Security Provider works with pmaxs/silex-locale ?

          即使我的用户选择了其他语言,一位同事建议我在登录和注销时保持en"(因为它有效).

          One collegue suggested me to stay in "en" for the login and logout (because it works), even if my user chose an other langage.

          你认为这是个好主意吗?(我不是 100% 好的,因为这样我无法翻译我的内容)

          Do you think it's a good idea? (I'm not 100% okay because this way I can't translate my content)

          由于我的问题没有答案,我尝试检查我的两条路线 /login_check/logout 以查看是否可以更改它们,执行你知道我在哪里可以找到它们吗?

          Since I have no anwser to my question, I tried to check my two routes /login_check and /logout to see if I can change them, do you know where I can find them?

          然后,我尝试在去这两条路线之前进行一些重定向,但不知道我该怎么做......这个想法:

          Then, I tried to make some redirection before going to those two routes, but don't know how I can do it...the idea :

          // If I log from those URL, it works
          /login
          /en/login
          
          // If I log from those, it doesn't works :
          /fr/login
          /fr/fr/login
          
          // So from the URL that doesn't works, I'd like to do :
          /fr/login ---> redirect to /login ---> execute code
          /fr/fr/login ---> redirect to /en/login ---> execute code
          

          /logout 也一样.知道我是否可以做到以及如何做到这一点?

          结束编辑

          PS:这是关于这个项目的另一个问题,我解释了我如何允许用户更改网站上的语言:Silex : 允许用户通过单击 html 元素并保持干净的 URL 来更改语言

          PS : Here is an other question about this project where I explain how I allow user to change langage on the website : Silex : allow user to change langage by clicking on html element and keeping clean URL

          推荐答案

          我想我设法通过这种方式解决了我的问题:

          I think I manage to solve my problem this way :

          1/为了避开 error 404,当我使用 en 以外的其他语言环境时登录和注销,我在 en 中重定向用户在我的 check_pathlogout 之前:

          1/ To dodge my error 404 where I login and logout when I have another locale than en, I redirect the user in en before my check_path and logout :

          // The login form action
          <form role="form" action="{{ locale_generate('en', 'login_check') }}" method="post">
          
          // The logout
          <a href="{{ locale_generate('en', 'logout') }}"> <span class="log">{{ 'logout'|trans }}</span></a>
          

          这样可以正常工作,但用户总是以英语返回,所以我必须在我的页面中重定向他,但使用与以前相同的语言环境.

          This way it works but user came back in english all the time, so I have to redirect him in my page but with the same locale than before.

          2/所以我在会话中添加选定的语言(如果我没有 $_SESSION['langue'],我使用我的默认语言环境作为值:en)

          2/ So I add the selected langage in session (if I have no $_SESSION['langue'], I use my default locale as value : en)

          //===============================================
          // My Ajax call where I send the selected langage value
          //===============================================
          $(".change_langue").on("click", function() {
              var new_langue = $(this).data("lg");
          
              $.ajax({
                  url: "{{ path('new-langue') }}",
                  type: 'POST',
                  data: {'langue': new_langue},
                  success: function (resp) {
                      console.log(resp);
                  },
                  error: function (resp) {
                      console.log(resp);
                  }
              });
          });
          
          //========================================================
          // My controller where I set the value in session
          //========================================================
          $app->post('/new-langue', function(Request $request) use ($app) {
              $new_langue = $request->get('langue');
          
              $app['session']->set('langue', $new_langue);
              $result['new_langue'] =  $app['session']->get('langue');
          
              return new Response(json_encode($result));
          
          })->bind('new-langue');
          

          3/然后我在注册 SecurityProvider 时更改了默认登录路径:

          3/ Then I change my default login path when I registered my SecurityProvider :

          $app->register(new SilexProviderSecurityServiceProvider(), array(
              'security.firewalls' => array(
                  'secured' => array(
                      'pattern' => '^/',
                      'anonymous' => true,
                      'form' => array(
                          'login_path' => 'login',
                          'check_path' => '/login_check',
                          'always_use_default_target_path' => true,  // I add this line
                          'default_target_path' => '/login/redirect' // I add this line
                      ),
                      'logout' => array(
                          'logout_path' => '/logout',
                          'invalidate_session' => true,                      
                      ),
                      'users' => function () use ($app) {
                          return new _mypixers_silexDAOUserDAO($app['db']);
                      },
                  ),
              ),
          ));
          

          4/现在在我的新 /login/redirect 控制器中检查 $_SESSION['langue'] 值并重定向到正确的语言:

          4/ And now in my new /login/redirect controller I check the $_SESSION['langue'] value and redirect to the right langage :

          //========================================================
          // LOGIN REDIRECT
          //========================================================
          $app->get('/login/redirect', function(Request $request) use ($app) {
              $session_langue = $app['session']->get('langue');
              if (empty($session_langue)) {
                  $session_langue = 'en';
              }
              return $app->redirect($app['locale.url_generator']->generate($session_langue, 'pixers'));
          
          })->bind('login_redirect');
          

          这样,当我使用 en 以外的其他语言环境登录或注销时,我不会再出现错误,并且用户仍使用当前语言.

          This way I have no more error when I login or logout with an other locale than en and the user stay in his current langage.

          PS:当我现在退出时,我仍然会回到英语,但我正在研究解决方案.完成后我会编辑我的答案

          PS : I still come back to english when I logout right now, but I'm working on a solution. I will edit my anwser when it's done

相关文章