<?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; login form</title>
	<atom:link href="http://www.newlifeclan.com/symfony/archives/tag/login-form/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之04创建一个登陆表单下</title>
		<link>http://www.newlifeclan.com/symfony/archives/407</link>
		<comments>http://www.newlifeclan.com/symfony/archives/407#comments</comments>
		<pubDate>Mon, 30 Mar 2015 10:46:08 +0000</pubDate>
		<dc:creator><![CDATA[napoleon]]></dc:creator>
				<category><![CDATA[实战教程]]></category>
		<category><![CDATA[login form]]></category>

		<guid isPermaLink="false">http://www.newlifeclan.com/symfony/?p=407</guid>
		<description><![CDATA[<p>好了，我们快完成了，真的！ 创建模板 创建login.html.twig文件（目录代码中可见）： [crayo [&#8230;]</p>
<p><a rel="nofollow" href="http://www.newlifeclan.com/symfony/archives/407">KU案例2之04创建一个登陆表单下</a>，首发于<a rel="nofollow" href="http://www.newlifeclan.com/symfony">Symfony中文教程</a>。</p>
]]></description>
				<content:encoded><![CDATA[<p>好了，我们快完成了，真的！</p>
<h2>创建模板</h2>
<p>创建login.html.twig文件（目录代码中可见）：</p>
<p><span id="more-407"></span></p><pre class="crayon-plain-tag">{# src/Yoda/UserBundle/Resources/views/Security/login.html.twig #}
{% if error %}
    &lt;div&gt;{{ error.message }}&lt;/div&gt;
{% endif %}

&lt;form action="{{ path('login_check') }}" method="post"&gt;
    &lt;label for="username"&gt;Username:&lt;/label&gt;
    &lt;input type="text" id="username" name="_username" value="{{ last_username }}" /&gt;

    &lt;label for="password"&gt;Password:&lt;/label&gt;
    &lt;input type="password" id="password" name="_password" /&gt;

    {#
        If you want to control the URL the user
        is redirected to on success (more details below)
        &lt;input type="hidden" name="_target_path" value="/account" /&gt;
    #}

    &lt;button type="submit"&gt;login&lt;/button&gt;
&lt;/form&gt;</pre><p>以上<tt class="docutils literal"><span class="pre">_username</span></tt> 和 <tt class="docutils literal"><span class="pre">_password</span></tt> 字段缺一不可，否则symfony无法取到值会输出一个login错误信息。当我们提交数据时，symfony会寻找这些字段，所以他们很重要。</p>
<blockquote><p>提示：你可以改变这些字段的名称，你可以google 搜索<tt class="docutils literal"><span class="pre">username_parameter</span></tt> and <tt class="docutils literal"><span class="pre">password_parameter</span></tt> options.</p></blockquote>
<p>让我们继承base.html.twig模板，添加一个小元素：</p><pre class="crayon-plain-tag">{# src/Yoda/UserBundle/Resources/views/Security/login.html.twig #}
{% extends '::base.html.twig' %}

{% block body %}
&lt;section class="login"&gt;
    &lt;article&gt;

        {% if error %}
            &lt;div class="error"&gt;{{ error.message }}&lt;/div&gt;
        {% endif %}

        &lt;form action="{{ path('login_check') }}" method="post"&gt;
            &lt;label for="username"&gt;Username:&lt;/label&gt;
            &lt;input type="text" id="username" name="_username" value="{{ last_username }}" /&gt;

            &lt;label for="password"&gt;Password:&lt;/label&gt;
            &lt;input type="password" id="password" name="_password" /&gt;

            &lt;button type="submit"&gt;login&lt;/button&gt;
        &lt;/form&gt;

    &lt;/article&gt;
&lt;/section&gt;
{% endblock %}</pre><p>&nbsp;</p>
<p>处理登录：login_check</p>
<p>是检查路由！还是控制器！检查模板！让我们试一试，一个错误提示：</p>
<p>Unable to generate a URL for the named route “login_check” as such route does not exist.</p>
<p>是检查路由，我们在模板中的表单里有一个action路径为login_check。所以我们要创建一个方法并且给他指定@Route为login_check：</p><pre class="crayon-plain-tag">// ...
// src/Yoda/UserBundle/Controller/SecurityController.php

/**
 * @Route("/login_check", name="login_check")
 */
public function loginCheckAction()
{
}</pre><p>我快疯了，不知道怎么办了。通常情况下，这意味着，你访问/login_check将执行控制器，因为没有返回任何东西，应该会爆出一个错误。说明我们的login_check还是普通的路由并没有和Security结合。</p>
<h2>配置login_path和check_path</h2>
<p>我们现在打开Security.yml并找到form_login配置：</p><pre class="crayon-plain-tag"># app/config/security.yml
# ...

firewalls:
    secured_area:
        pattern:    ^/
        form_login:
            check_path: _security_check
            login_path: /my-login-url
        # ...</pre><p>你应该更改login_path为/login ,当用户没有角色时，他会被重定向到登录页面</p>
<p>你还应该更改check_path为/login_check ,当用户提交时Security会判断它填写的登录信息是否正确。</p>
<p>现在你去访问 /new.我们可以看到页面重定向到 /login 页面，感谢login_path的关键配置。</p>
<p>使用和了解登录过程</p>
<p>现在，让我告诉你symfony安全系统的牛逼之一。当我们使用user和userpass登录时，他工作了！我们能看到username在web debug工具中并且还分配了一个角色。到底发生了什么事情？</p>
<p>但我们提交，symfony安全系统拦截了这个请求，并且处理了登录信息。他是这样工作的只要你使用post方式提交_username和_password到/login_check地址。这个URL时非常特殊的，因为该路由被配置到Security.yml的check_path键上。它就永远也不会执行loginCheckAction方法，因为symfony拦截了他的post请求。</p>
<p>那我们的user和userpass从哪里来的？其实就是Security.yml里的默认用户：</p><pre class="crayon-plain-tag"># app/config/security.yml
# ...
providers:
    in_memory:
        memory:
            # this was here when we started: 2 hardcoded users
            users:
                user:  { password: userpass, roles: [ 'ROLE_USER' ] }
                admin: { password: adminpass, roles: [ 'ROLE_ADMIN' ] }</pre><p>我们可以再一分钟内，将用户加载到数据库。</p>
<p><a rel="nofollow" href="http://www.newlifeclan.com/symfony/archives/407">KU案例2之04创建一个登陆表单下</a>，首发于<a rel="nofollow" href="http://www.newlifeclan.com/symfony">Symfony中文教程</a>。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.newlifeclan.com/symfony/archives/407/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>KU案例2之03创建一个登陆表单上</title>
		<link>http://www.newlifeclan.com/symfony/archives/405</link>
		<comments>http://www.newlifeclan.com/symfony/archives/405#comments</comments>
		<pubDate>Mon, 30 Mar 2015 08:33:30 +0000</pubDate>
		<dc:creator><![CDATA[napoleon]]></dc:creator>
				<category><![CDATA[实战教程]]></category>
		<category><![CDATA[login form]]></category>

		<guid isPermaLink="false">http://www.newlifeclan.com/symfony/?p=405</guid>
		<description><![CDATA[<p>在这一章我们会构建一个真正的登录表单。 有一个非常流行的开源bundle他叫Fosuserbundle，他可以 [&#8230;]</p>
<p><a rel="nofollow" href="http://www.newlifeclan.com/symfony/archives/405">KU案例2之03创建一个登陆表单上</a>，首发于<a rel="nofollow" href="http://www.newlifeclan.com/symfony">Symfony中文教程</a>。</p>
]]></description>
				<content:encoded><![CDATA[<p>在这一章我们会构建一个真正的登录表单。</p>
<p>有一个非常流行的开源bundle他叫Fosuserbundle，他可以替你完成很多下面我们要做的事情。本章构建一个登陆系统后，你会更好的理解它是如何工作的。因此，希望你在本章节后，不妨看看Fosuserbundle。</p>
<p><span id="more-405"></span></p>
<h2>手动创建一个Bundle</h2>
<p>让我们来创建一个新的UserBundle。我们可以使用命令行<span class="pre">app/console</span> <span class="pre">generate:bundle来创建，但是我这次手动创建。其实很容易：</span></p>
<p>仅仅需要创建一个UserBundle目录，并在目录里创建一个空的UserBundle类。一个bundle只不过是一个目录和一个bundle类：</p><pre class="crayon-plain-tag">// src/Yoda/UserBundle/UserBundle.php
namespace Yoda\UserBundle;

use Symfony\Component\HttpKernel\Bundle\Bundle;

class UserBundle extends Bundle
{
}</pre><p>现在，我们只需要在AppKernel中激活它。</p><pre class="crayon-plain-tag">// app/AppKernel.php
// ...

public function registerBundles()
{
    $bundles = array(
        // ...
        new Yoda\UserBundle\UserBundle(),
    );

    // ...
}</pre><p></p>
<h2> 登录表单控制器（Controller）</h2>
<p>你需要创建一个Controller目录，在这个目录里添加一个SecurityController类。给这个类添加一个loginAction方法。他是用来渲染我们的登录表单：</p><pre class="crayon-plain-tag">// src/Yoda/UserBundle/Controller/SecurityController.php
namespace Yoda\UserBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class SecurityController extends Controller
{
    public function loginAction()
    {
    }
}</pre><p></p>
<h2>
使用Annotation 路由</h2>
<p>之前我们添加了loginAction，我们需要一个路由来让他能够访问。</p>
<p>首先添加Route annotation的命名空间：</p><pre class="crayon-plain-tag">// src/Yoda/UserBundle/Controller/SecurityController.php
// ...

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;

class SecurityController extends Controller
{
    // ...
}</pre><p>现在，我们开始添加annotation路由配置的正确方法：</p><pre class="crayon-plain-tag">// src/Yoda/UserBundle/Controller/SecurityController.php
// ...

/**
 * @Route("/login", name="login_form")
 */
public function loginAction()
{
    // ... todo still..
}</pre><p>最后，我们要添加一段代码在主routing.yml文件中，告诉symfony在UserBundle中使用annotation路由：</p><pre class="crayon-plain-tag"># app/config/routing.yml
# ...

user_routes:
    resource: "@UserBundle/Controller"
    type: annotation</pre><p>请记住，symfony永远不会自动查找路由文件，所以我们每次都要手动在这里添加。</p>
<p>酷-在你的浏览器中访问 /login。它已经不是404的错误页面了，这意味着该路径可以正常工作了。现在我们来填写控制器！</p>
<h2>添加loginAction的逻辑</h2>
<p>不要忘了添加<tt class="docutils literal"><span class="pre">SecurityContextInterface和<tt class="docutils literal">Request类：</tt></span></tt></p><pre class="crayon-plain-tag">// src/Yoda/UserBundle/Controller/SecurityController.php
namespace Yoda\UserBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\HttpFoundation\Request;
// ...

class SecurityController extends Controller
{
    /**
     * @Route("/login", name="login")
     */
    public function loginAction(Request $request)
    {
        $session = $request-&gt;getSession();

        // get the login error if there is one
        if ($request-&gt;attributes-&gt;has(SecurityContextInterface::AUTHENTICATION_ERROR)) {
            $error = $request-&gt;attributes-&gt;get(
                SecurityContextInterface::AUTHENTICATION_ERROR
            );
        } else {
            $error = $session-&gt;get(SecurityContextInterface::AUTHENTICATION_ERROR);
            $session-&gt;remove(SecurityContextInterface::AUTHENTICATION_ERROR);
        }

        return $this-&gt;render(
            'AcmeSecurityBundle:Security:login.html.twig',
            array(
                // last username entered by the user
                'last_username' =&gt; $session-&gt;get(SecurityContextInterface::LAST_USERNAME),
                'error'         =&gt; $error,
            )
        );
    }</pre><p>该方法只是呈现了一个登录模板：他不处理提交和不检查用户名和密码是否正确。还有另一层功能是，它会发现登录的错误信息并返回模板仅此而已。</p>
<h2>使用Annotation 快捷方式渲染模板：</h2>
<p>第一次使用我们要添加一个use声明，现在也把@Template方法放到注释中。loginAction返回数组即可渲染到模板中。</p><pre class="crayon-plain-tag">// src/Yoda/UserBundle/Controller/SecurityController.php
// ...

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;

class SecurityController extends Controller
{
    /**
     * @Route("/login", name="login_form")
     * @Template()
     */
    public function loginAction()
    {
        // ...

        return array(
            // last username entered by the user
            'last_username' =&gt; $session-&gt;get(SecurityContextInterface::LAST_USERNAME),
            'error'         =&gt; $error,
        );
    }
}</pre><p>@Template会自动呈现模板，我们省去了很多代码。这很酷。</p>
<p><a rel="nofollow" href="http://www.newlifeclan.com/symfony/archives/405">KU案例2之03创建一个登陆表单上</a>，首发于<a rel="nofollow" href="http://www.newlifeclan.com/symfony">Symfony中文教程</a>。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.newlifeclan.com/symfony/archives/405/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
