我有一个 Symfony 4.4 项目。登录、身份验证和授权在 Web 上运行良好。
为了在单元测试中模拟身份验证,我使用 Symfony 的示例。
...但这不起作用。用户在单元测试中未经过身份验证。我收到一条未经授权的错误消息“访问此资源需要完全身份验证。”
我的测试:
namespace App\Tests\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\BrowserKit\Cookie;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Guard\Token\PostAuthenticationGuardToken;
use App\Entity\User;
use Doctrine\ORM\EntityManagerInterface;
class DefaultControllerTest extends WebTestCase
{
private $client = null;
public function setUp()
{
$this->client = static::createClient();
}
public function testJsonUserEndpoint()
{
$this->logIn();
$crawler = $this->client->request('GET', '/json/user');
$this->assertNotContains('invalid_credentials', $this->client->getResponse()->getContent());
}
private function logIn()
{
$user = self::$container->get(EntityManagerInterface::class)->getRepository(User::class)->findOneByMail('[email protected]');
$session = $this->client->getContainer()->get('session');
$firewallName = 'main';
$firewallContext = 'main';
$token = new PostAuthenticationGuardToken($user, $firewallName, ['ROLE_USER']);
$session->set('_security_'.$firewallContext, serialize($token));
$session->save();
$cookie = new Cookie($session->getName(), $session->getId());
$this->client->getCookieJar()->set($cookie);
}
}
我的防火墙:
main:
anonymous:
secret: '%env(APP_SECRET)%'
remember_me:
always_remember_me: true
secret: '%env(APP_SECRET)%'
provider: session_user_provider
guard:
authenticators:
- App\Security\Authenticator\LoginAuthenticator
- App\Security\Authenticator\MobileBridgeAuthenticator
- App\Security\Authenticator\BearerTokenAuthenticator
- App\Security\Authenticator\HashAuthenticator
- App\Security\Authenticator\ClientAuthenticator
entry_point: App\Security\Authenticator\LoginAuthenticator
logout:
path: execute_logout
target: render_login
单元测试失败:
1) App\Tests\Controller\DefaultControllerTest::testJsonUserEndpoint
Failed asserting that '{"status":"invalid_credentials","errors":["Invalid Credentials"],"debug":"Full authentication is required to access this resource.","error":"Unauthorized"}' does not contain "invalid_credentials".
如何在不使用登录表单的情况下在单元测试中验证用户身份?
问题是我没有将角色与用户一起存储在数据库中——它们被添加到我的身份验证器中——并且将角色传递给
PostAuthenticationGuardToken
是不够的。我还必须将它们添加到令牌中的用户:
$user->setRoles(['ROLE_USER']);
$token = new PostAuthenticationGuardToken($session_user, $firewallName, ['ROLE_USER']);
其实,Token 的角色是什么并不重要,只要它是一个数组即可:
$user->setRoles(['ROLE_USER']);
$token = new PostAuthenticationGuardToken($session_user, $firewallName, []);