<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Symfony中文教程 &#187; UserProviderInterface</title>
	<atom:link href="http://www.newlifeclan.com/symfony/archives/tag/userproviderinterface/feed" rel="self" type="application/rss+xml" />
	<link>http://www.newlifeclan.com/symfony</link>
	<description>站在巨人肩膀上的phpweb框架</description>
	<lastBuildDate>Fri, 12 Dec 2025 00:58:27 +0000</lastBuildDate>
	<language>zh-CN</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.0.38</generator>
	<item>
		<title>KU案例2之13UserProvider:自定义的方式加载Security用户</title>
		<link>http://www.newlifeclan.com/symfony/archives/434</link>
		<comments>http://www.newlifeclan.com/symfony/archives/434#comments</comments>
		<pubDate>Sat, 11 Apr 2015 04:33:03 +0000</pubDate>
		<dc:creator><![CDATA[napoleon]]></dc:creator>
				<category><![CDATA[实战教程]]></category>
		<category><![CDATA[UserProviderInterface]]></category>

		<guid isPermaLink="false">http://www.newlifeclan.com/symfony/?p=434</guid>
		<description><![CDATA[<p>我们的目的是让用户可以使用用户名或者email登录。如果我们能够让Security系统使用我们闪亮牛逼的fin [&#8230;]</p>
<p><a rel="nofollow" href="http://www.newlifeclan.com/symfony/archives/434">KU案例2之13UserProvider:自定义的方式加载Security用户</a>，首发于<a rel="nofollow" href="http://www.newlifeclan.com/symfony">Symfony中文教程</a>。</p>
]]></description>
				<content:encoded><![CDATA[<p>我们的目的是让用户可以使用用户名或者email登录。如果我们能够让Security系统使用我们闪亮牛逼的findOneByUsernameOrEmail方法查找用户并登录，那么今天的任务就完成了。</p>
<p><span id="more-434"></span></p>
<p>打开security.yml并移除providers键下的属性，重新填写他们：</p><pre class="crayon-plain-tag"># app/config/security.yml
security:
    # ...

    providers:
        our_database_users:
            entity: { class: UserBundle:User }</pre><p>现在试试，天呀！报了一个错误：</p>
<p>&gt; The Doctrine repository “YodaUserBundleEntityUserRepository” must implement UserProviderInterface.</p>
<h2></h2>
<h2>UserProviderInterface</h2>
<p>没有这些属性，doctrine不知道如何查找用户。相反，它试图调用我们UserRepository中的一个方法。但对于这个工作，我们的UserRepository类必须实现UserProviderInterface。</p>
<p>因此，让我们打开UserRepository</p><pre class="crayon-plain-tag">// src/Yoda/UserBundle/Entity/UserRepository.php
// ...

use Symfony\Component\Security\Core\User\UserProviderInterface;

class UserRepository extends EntityRepository implements UserProviderInterface
{
    // ...
}</pre><p>和往常一样不要忘记使用use声明！这个接口提供了三个方法：<tt class="docutils literal"><span class="pre">refreshUser</span></tt>, <tt class="docutils literal"><span class="pre">supportsClass</span></tt> and<tt class="docutils literal"><span class="pre">loadUserByUsername</span></tt>. 我都粘贴进来：</p><pre class="crayon-plain-tag">// src/Yoda/UserBundle/Entity/UserRepository.php
// ...

use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;

class UserRepository extends EntityRepository implements UserProviderInterface
{
    // ...

    public function loadUserByUsername($username)
    {
        // todo
    }

    public function refreshUser(UserInterface $user)
    {
        $class = get_class($user);
        if (!$this-&gt;supportsClass($class)) {
            throw new UnsupportedUserException(sprintf(
                'Instances of "%s" are not supported.',
                $class
            ));
        }

        if (!$refreshedUser = $this-&gt;find($user-&gt;getId())) {
            throw new UsernameNotFoundException(sprintf('User with id %s not found', json_encode($user-&gt;getId())));
        }

        return $refreshedUser;
    }

    public function supportsClass($class)
    {
        return $this-&gt;getEntityName() === $class
            || is_subclass_of($class, $this-&gt;getEntityName());
    }
}</pre><p>&nbsp;</p>
<p>填充loadUserByUsername</p>
<p>这个loadUserByUsername方法很重要，因为当你使用User对象的username登录时，symfony就会调用他。所以在这里我们可以使用任何逻辑，例如 可以返回用户名“Jar Jar Binks”：</p><pre class="crayon-plain-tag">public function loadUserByUsername($username)
{
    if ($username == 'jarjarbinks') {
        // nope!
        return;
    }
}</pre><p>我们在这里可以使用我们之前创建的findOneByUsernameOrEmail方法。如果没有发现用户，我们抛出一个UsernameNotFoundException异常：</p><pre class="crayon-plain-tag">// src/Yoda/UserBundle/Entity/UserRepository.php
// ...

class UserRepository extends EntityRepository implements UserProviderInterface
{
    // ...

    public function loadUserByUsername($username)
    {
        $user = $this-&gt;findOneByUsernameOrEmail($username);

        if (!$user) {
            throw new UsernameNotFoundException('No user found for username '.$username);
        }

        return $user;
    }

    // ... refreshUser and supportsClass from above...
}</pre><p>尝试使用电子邮件登录。他工作了！在幕后，symfony调用loadUserByUsername方法，并传递了我们提交的用户名。我们返回了一个正确的用户对象并认证他是正常的用户。我们没有去验证密码，因为这块symfony处理还和以前一样。</p>
<p>好了，你已经掌握了很多关于security和doctrine的知识！给自己鼓鼓掌吧，因为你已经学会了使用symfony和doctrine的复杂知识。现在你已经完成了一个优雅的登录系统，而且还能给他很多的控制，下章我们将介绍用户注册。</p>
<p>&nbsp;</p>
<p><a rel="nofollow" href="http://www.newlifeclan.com/symfony/archives/434">KU案例2之13UserProvider:自定义的方式加载Security用户</a>，首发于<a rel="nofollow" href="http://www.newlifeclan.com/symfony">Symfony中文教程</a>。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.newlifeclan.com/symfony/archives/434/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
