Уловимая неустранимая ошибка: аргумент 1 передан …CsrfTokenManager::isTokenValid() должен быть экземпляром …CsrfToken, заданная строка

#php #symfony #symfony3.x

#php #symfony #symfony3.x

Вопрос:

В настоящее время я обновляю систему, работающую на существующем Symfony 2.3 (в настоящее время 3.0.9), и я проверяю операцию. Когда я попробовал возможность изменить статус статьи на выбранный статус, я получил сообщение об ошибке. У вас есть какие-либо советы о том, как определить причину?

Код BaseArticleController.php

     /**
     * Article status change
     */
    protected function updateArticleStatusAction(Request $request, $ids)
    {
        // CSRF token check
        $token = $request->request->get('_csrf_token');

        if (!$this->get('security.csrf.token_manager')->isTokenValid('authenticate', $token))
 {
            throw new HttpException("400", "The CSRF token is invalid. Please try to resubmit
 the form.");
        }

        // Check status
        $articleStatus = $request->request->get("articleStatus");
        if (!in_array($articleStatus, Parameters::getArticleStatusKeys())) {
            throw new HttpException("400", "articleStatus is invalid.");
        }

        // Status change
        try {
            $ids = explode(',', $ids);
            $count = $this->getArticleService()->updateArticleStatus($ids, $articleStatus, $t
his->getShop());
            if ($count) {
                $this->get('session')->getFlashBag()->add('success', "{$count}The status of the article has changed.");
            }
        } catch (ArticleValidationException $e) {
            $article = $e->getArticle();
            $statusArray = Parameters::getArticleStatus();
            $this->get('session')->getFlashBag()->add(
                'error',
                sprintf(
                    "Article ID:% d could not be "% s". Please check your input.",
                    $article->getId(),
                    $statusArray[$article->getArticleStatus()]
                )
            );
        }

        // redirect
        $backurl = $request->query->get("backurl");
        if (!$backurl) {
            $backurl = $this->generateUrl($this->indexRoute);
        }
        return $this->redirect($backurl);
    }

 

ArticleController.php

     /**
     * Article status change
     *
     * @Method("POST")
     * @Route("/article/{ids}/articleStatus")
     * @Secure(roles="ROLE_HQ_MANAGE")
     */
    public function updateArticleStatusAction(Request $request, $ids)
    {
        return parent::updateArticleStatusAction($request, $ids);
    }
 

index.html.twig

     {# Status change form #}
    <form method="post" class="updateArticleStatus" data-url="{{ path("ahi_sp_admin_hq_article_updatearticlestatus", {"ids": "__ids__"}) }}">
        <input type="hidden" name="methods" value="POST">
        <input type="hidden" name="_csrf_token" value="{{ csrf_token("authenticate") }}">
        <input type="hidden" name="articleStatus" value="">
    </form>
 

security.yml

 security:
    firewalls:
        secured_area2:
            pattern:    ^/admin/sp/
            anonymous: ~
            form_login:
                login_path:  /admin/sp/login
                check_path:  /admin/sp/login_check
                csrf_token_generator: security.csrf.token_manager
                always_use_default_target_path: true
                default_target_path:            /admin/sp/
                target_path_parameter:          _target_path
                use_referer:                    false

            logout:
                path:   /admin/sp/logout
                target: /admin/sp/login

            remember_me:
                secret:      "%secret%"
                lifetime: 2592000 # 30 days in seconds
                path:     /
                domain:   ~ # Defaults to the current domain from $_SERVER
                always_remember_me: true

        secured_area:
            pattern:    ^/admin/
            anonymous: ~
            form_login:
                login_path:  /admin/login
                check_path:  /admin/login_check

                csrf_token_generator: security.csrf.token_manager
                always_use_default_target_path: true
                default_target_path:            /admin/
                target_path_parameter:          _target_path
                use_referer:                    false

            logout:
                path:   /admin/logout
                target: /admin/login
 

Комментарии:

1. Приведенный ниже ответ должен помочь вам преодолеть вашу конкретную ошибку, но у вас действительно есть работа, вырезанная для вас, поскольку 2.3 довольно древний. Возможно, было бы лучше начать с текущей версии (4.4 или 5.2 в зависимости от ваших целей), а затем выполнить копирование / вставку обновления. Если вы действительно хотите продолжить свой текущий путь, сначала обновите до 2.8. С 2.8 большая часть вашего кода 2.3 должна продолжать работать, но вы будете получать предупреждения о таких вещах, как ваши токены csrf. Устраните предупреждения, затем перейдите к 3.4.

2. @Cerad Спасибо за ваш комментарий. Кажется, лучше тщательно проверить предостережение в 2.8. Когда лучше скопировать / вставить код непосредственно в Symfony 4.4?

3. За прошедшие годы в общую структуру Symfony было внесено немало изменений. Если приложение необходимо поддерживать на неопределенный срок, я склоняюсь к тому, чтобы потратить время на копирование / вставку / изменение. По крайней мере, вы узнаете совсем немного о 4.4. Если вам просто отчаянно нужно запустить что-то под обновленной версией PHP и вы не планируете много работать с приложением, то обычный процесс обновления может быть лучшим. И не упускайте из виду возможность перехода непосредственно к 5.x .

4. @Cerad Спасибо тебе. Это лучше решать в зависимости от размера приложения. Это не так уж сложно, поэтому я хотел бы продолжить его обновление.

Ответ №1:

В сообщении также содержится достаточно подробностей для отладки, аргумент 1 (в вашем случае «аутентификация») должен быть токеном crsf. Попробуйте это:

 $csrf_token = new CsrfToken('authenticate', $token);

$this->get('security.csrf.token_manager')->isTokenValid($csrf_token)