1

I have the following problem. When I run analyse on my src folder, I get this error

 ------ ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  Line   Security/CustomerAuthenticator.php
 ------ ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  38     Parameter #1 $userIdentifier of class Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge constructor expects string, bool|float|int|string given.
  39     Parameter #1 $password of class Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials constructor expects string, bool|float|int|string given.
  41     Parameter #2 $csrfToken of class Symfony\Component\Security\Http\Authenticator\Passport\Badge\CsrfTokenBadge constructor expects string|null, bool|float|int|string|null given.
  53     Cannot call method getRoles() on Symfony\Component\Security\Core\User\UserInterface|null.

The main problem is, that I didn't wrote the Authenticator, so did Symfony. I used maker bundle to make user, and authenticator, and I barely changed anything inside code (I only added supports method, otherwise authenticator wouldn't work)

CustomerAuthenticator

<?php

namespace App\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\Core\Security;
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 CustomerAuthenticator extends AbstractLoginFormAuthenticator
{
    use TargetPathTrait;

    public const LOGIN_ROUTE = 'app_login';

    private UrlGeneratorInterface $urlGenerator;

    public function __construct(UrlGeneratorInterface $urlGenerator)
    {
        $this->urlGenerator = $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);
        }

        $user = $token->getUser();
        if (in_array('ROLE_ADMIN', $user->getRoles(), true)) {
            return new RedirectResponse($this->urlGenerator->generate('admin.adminpanel'));
        }

        // For example:
        // return new RedirectResponse($this->urlGenerator->generate('some_route'));
        return new RedirectResponse($this->urlGenerator->generate('app_home'));
    }

    protected function getLoginUrl(Request $request): string
    {
        return $this->urlGenerator->generate(self::LOGIN_ROUTE);
    }

    public function supports(Request $request): bool
    {
        return self::LOGIN_ROUTE === $request->attributes->get('_route')
               && $request->isMethod('POST');
    }

}

1 Answer 1

1

Maybe too strict level in phpstan? What did you expect from boilerplate code? =) Phpstan says, what's wrong. On line 38 you pass $username variable, which you get from request. But it can be not only string in request, what phpstan says. Cast to string, or maybe better - check if that string. Phpstan smart enough to realize, that it's exactly string after check. Same with others. Normally that's not a big issue and in most cases it would work as expected. But better to fix all phpstan issues on level at least 7.

For example:

$username = (string)$request->request->get('username', '');

or

if (!is_string($request->request->get('_csrf_token'))) {
    throw new AuthenticationException(''); // or maybe csrf token exception
}
Sign up to request clarification or add additional context in comments.

1 Comment

I casted to the string actually, and now works! Thanks for your time, and help!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.