4

我正在使用 fosUserBundle 建立一个站点。我需要编写一些单元测试,但我似乎无法让身份验证正常工作以与它们一起使用。我已经尝试了一些没有运气的方法。

方法 1 - 安全设置中的链提供程序以进行我可以依赖的标准登录。当我这样做时,唯一有效的身份验证是 in_memory 提供程序,这意味着我可以使用管理员用户登录,但不能使用 fosUserBundle 创建的任何用户

安全.yml

安全:
    编码器:
        “FOS\UserBundle\Model\UserInterface”:明文
        “Symfony\Component\Security\Core\User\User”:纯文本

    提供者:
        链提供者:
            提供者:[in_memory,fos_userbundle]
        在记忆中:
            用户:
                管理员:{密码:管理员,角色:['ROLE_ADMIN']}
        fos_userbundle:
            id:fos_user.user_manager


    防火墙:
        主要的:
            模式:^/
            表单登录:
                提供者:fos_userbundle
                登录路径:/
                csrf_provider:form.csrf_provider
                default_target_path:/媒体
            注销:真
            匿名:真实
            http_basic:
                提供者: in_memory

方法 2- 我在单元测试的设置中创建了一个用户。但是使用这种方法,我永远无法使用我刚刚创建的用户登录,我不需要用户确认。

公共功能设置(){

        $kernel = 静态::createKernel();
        $this->repo = $kernel->boot();
        $this->repo = $kernel->getContainer();

        $userManager = $this->repo->get('fos_user.user_manager');

        $email = "testing".(string) self::newRandomNumber()."@test.com";
        $un = "test".(string) self::newRandomNumber();
        $fn = "测试";
        $ln = "激光";
        $pwd = "密码1";

        $user = $userManager->createUser();

        $user->setEmail($email);
        $user->setUsername($un);
        $user->setFirstName($fn);
        $user->setLastName($ln);
        $user->setPlainPassword($pwd);
        $user->setBimStaff(True);

        // 将用户持久化到数据库         
        $userManager->updateUser($user);

        $this->user = $user;

        $this->client = static::createClient();
        $crawler = $this->client->request('GET', '/');

        $form = $crawler->selectButton('登录')->form();

        // 设置一些值
        $un = 'Lucas'.self::newRandomNumber();
        $form['_username'] = $un;
        $form['_password'] = $pwd;

        // 提交表单

        $crawler = $this->client->submit($form);
        print_r($this->client->getResponse());

        $this->client->followRedirects();

    }

我已经尝试过以表单和 http 基本身份验证登录,但似乎都不起作用。

有人有什么建议吗?

谢谢,科里

4

2 回答 2

4

嗯,如果您在安全性中链接提供者,您似乎不能只使用其中一个提供者,至少这为我解决了这个问题。

// security.yml 
providers:
    chain_provider:
        providers: [in_memory, fos_userbundle]
    in_memory:
        users:
            admin: { password: admin, roles: [ 'ROLE_ADMIN' ] }
    fos_userbundle:
        id: fos_user.user_manager


firewalls:
    main:
        pattern: ^/
        form_login:
            provider: chain_provider
            login_path:  /
            csrf_provider: form.csrf_provider
            default_target_path: /media
        logout:       true
        anonymous:    true
        http_basic:
            provider: chain_provider

由于某种原因,一旦我将两个提供商都更改为chain_provider它就开始合作。

我的单元测试现在看起来像这样

public function setUp() {

    $kernel = static::createKernel();
    $this->repo = $kernel->boot();
    $this->repo = $kernel->getContainer();


    $this->client = static::createClient(array(), array(
        'PHP_AUTH_USER' => 'admin',
        'PHP_AUTH_PW'   => 'admin',
    ));
    $this->client->followRedirects();

}

如果复制此内容,我建议您为您的用户使用更强的密码:)

于 2012-05-02T17:50:12.870 回答
1

我有同样的问题,但我希望选项 2 起作用。你的例子几乎就在那里,帮助了我。我认为它对您不起作用的原因是用户未启用。FOSUserBundle 中的用户构造函数默认会创建禁用用户,所以你必须调用$user->setEnable(true)

这是我的工作示例

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\BrowserKit\Cookie;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;

class MyControllerTest extends WebTestCase
{
    private $client = null;

    public function setUp()
    {
        $this->client = static::createClient();
    }

    private function logIn()
    {
        $session = $this->client->getContainer()->get('session');

        $userManager = $this->client->getContainer()->get('fos_user.user_manager');

        $user=$userManager->findUserByUsername('tester');
        if (!$user) {
            $user = $userManager->createUser();

            $user->setEmail('test@example.com');
            $user->setUsername('tester');
            $user->setPlainPassword('foo');
            $user->setEnabled(true);
            $user->addRole('ROLE_SUPER_ADMIN');

            $userManager->updateUser($user);
        }

        $firewall = 'main_firewall';
        $token = new UsernamePasswordToken($user, null, $firewall, array('ROLE_SUPER_ADMIN'));

        $session->set('_security_'.$firewall, serialize($token));
        $session->save();

        $cookie = new Cookie($session->getName(), $session->getId());
        $this->client->getCookieJar()->set($cookie);
    }

    public function testCompleteScenario()
    {
        $this->logIn();

        $crawler = $this->client->request('GET', '/foo/');
        $this->assertEquals(200, $this->client->getResponse()->getStatusCode(),
            "Unexpected HTTP status code for GET /foo/".$this->client->getResponse()->getContent());

    }

}
于 2015-05-31T07:53:20.627 回答