Symfony #[CurrentUser] attribute returns null

3.1k Views Asked by At
<?php

declare(strict_types=1);

namespace App\Controller\User;

use App\Entity\User;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Attribute\CurrentUser;

#[Route('/users', name: 'user.')]
class UserController extends AbstractController
{
    #[Route(name: 'list')]
    public function list(#[CurrentUser] ?User $user, Request $request): Response { 
        dd($user->getFirstName());
    }

Say's Call to a member function getFirstName() on null

But I'm authorized. At the Symfony Profiler it shows that I'm logged in.

Env: PHP 8.0.11 Symfony 5.3.9

3

There are 3 best solutions below

1
Denzel Brazhnikoff On BEST ANSWER

The correct details on solution are provided by https://stackoverflow.com/users/1144627/will-b Symfony #[CurrentUser] attribute returns null

The issue is caused by enabled ParamConvertor (sensio/framework-extra-bundle). It can't resolve the User due to lack definitions of how to fetch the Entity from DB, so it sets the $user variable to null because of nullable #[CurrentUser] ?User $user . If you want to keep functionality of param converter and #[CurrentUser] attribute same time, you should disable auto convertion #

config/packages/sensio_framework_extra.yaml
sensio_framework_extra:
    request:
        converters: true
        auto_convert: false

And define route params each time manually. Sources: https://symfony.com/bundles/SensioFrameworkExtraBundle/current/annotations/converters.html https://symfony.com/blog/new-in-symfony-5-2-controller-argument-attributes https://symfony.com/doc/current/controller/argument_value_resolver.html

Solution to avoid such issues: Read the docs at 200% browser scale.

3
Ouss Ma L'aire Bien On

if your controller extends "AbstractController" you can use $this->getUser() to get the current User.

in your list function you are not giving an user id neither an $user so $user is rationally null

#[Route('/users', name: 'user.')]
class UserController extends AbstractController
 {
#[Route(name: 'list')]
public function list( Request 
$request): Response { 
    dd($this->getUser()->getFirstName());
}
1
floriankapaun On

As pointed out by others, the problem is indeed the enabled ParamConverter in Sensio Framework Extra Bundle.

But instead of completely disabling it, you could change the typehinting in your Controller from User to UserInterface like this:

<?php

use Symfony\Component\Security\Core\User\UserInterface;
// ...

public function list(#[CurrentUser] ?UserInterface $user, Request $request): Response {
    assert($user instanceof User);
    dd($user->getFirstName());
}

Example of full Controller:

<?php

declare(strict_types=1);

namespace App\Controller\User;

use App\Entity\User;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Http\Attribute\CurrentUser;

#[Route('/users', name: 'user.')]
class UserController extends AbstractController
{
    #[Route(name: 'list')]
    public function list(#[CurrentUser] ?UserInterface $user, Request $request): Response {
        assert($user instanceof User);
        dd($user->getFirstName());
    }
}