这是我的实体:
<?php
namespace Trade\TradeBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* @ORM\Entity(repositoryClass = "Trade\TradeBundle\Repository\UserRepository")
* @ORM\Table(name = "user")
* @UniqueEntity(fields = "username", message = "The username already exists.")
*/
class User implements UserInterface
{
/**
* @ORM\id
* @ORM\Column(name = "id", type = "integer")
* @ORM\GeneratedValue(strategy = "AUTO")
*/
protected $id;
/**
* @ORM\Column(name = "username", type = "string", length = 20, unique = true)
*
* @Assert\NotBlank(
* message = "The username cannot be blank."
* )
*/
protected $username;
/**
* @ORM\Column(name = "password", type = "string", length = 40)
*
* @Assert\NotBlank(
* message = "The password cannot be blank."
* )
* @Assert\MinLength(
* limit = 8,
* message = "The password '{{ value }}' is too short. It should have {{ limit }} characters or more."
* )
* @Assert\MaxLength(
* limit = 16,
* message = "The password '{{ value }}' is too long. It should have {{ limit }} characters or less."
* )
*/
protected $password;
/**
* @ORM\Column(type = "string", length = 40)
*/
protected $salt;
public function __construct()
{
$this->salt = md5(uniqid(null, true));
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set username
*
* @param string $username
*/
public function setUsername($username)
{
$this->username = $username;
}
/**
* Get username
*
* @return string
*/
public function getUsername()
{
return $this->username;
}
/**
* Set password
*
* @param string $password
*/
public function setPassword($password)
{
$this->password = $password;
}
/**
* Get password
*
* @return string
*/
public function getPassword()
{
return $this->password;
}
public function getSalt()
{
return $this->salt;
}
public function getRoles()
{
return array('ROLE_USER');
}
public function eraseCredentials()
{
}
public function equals(UserInterface $user)
{
return $this->username === $user->getUsername();
}
}
这是我的存储库:
<?php
namespace Trade\TradeBundle\Repository;
use Doctrine\ORM\EntityRepository;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* UserRepository
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class UserRepository extends EntityRepository implements UserProviderInterface
{
public function loadUserByUsername($username)
{
return $this->getEntityManager()->findOneByUsername($username);
}
public function refreshUser(UserInterface $user)
{
return $this->loadUserByUsername($user->getUsername());
}
public function supportsClass($class)
{
return $class === 'Trade\TradeBundle\Entity\User';
}
}
这是security.yml:
security:
encoders:
Trade\TradeBundle\Entity\User:
algorithm: sha1
encode_as_base64: false
iterations: 1
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
providers:
main:
entity: { class: TradeTradeBundle:User, property: username }
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
secured_area:
pattern: ^/
form_login:
check_path: /account/signin_check
login_path: /account/signin
logout:
path: /account/signout
target: /
anonymous: ~
access_control:
- { path: ^/account/signin, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/account, roles: ROLE_USER }
- { path: ^/admin, roles: ROLE_ADMIN }
这是我的控制器操作:
/**
* @Route("/account/signin", name = "account_signin")
* @Route("/account/signin_check", name = "account_signin_check")
* @Method({"GET", "POST"})
*/
public function signInAction()
{
$request = $this->getRequest();
$session = $request->getSession();
$user = new \Trade\TradeBundle\Entity\User();
$form = $this->createForm(new \Trade\TradeBundle\Form\Type\UserType(), $user);
if ($request->attributes->has(SecurityContext::AUTHENTICATION_ERROR))
{
$error = $request->attributes->get(SecurityContext::AUTHENTICATION_ERROR);
}
else
{
$error = $session->get(SecurityContext::AUTHENTICATION_ERROR);
$session->remove(SecurityContext::AUTHENTICATION_ERROR);
}
return $this->render('TradeTradeBundle:Account:signin.html.twig', array('form' => $form->createView(), 'error' => $error));
}
这是我的表格类:
<?php
namespace Trade\TradeBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;
class UserType extends AbstractType
{
public function buildForm(FormBuilder $builder, array $options)
{
$builder->add('username', 'text', array('required' => false));
$builder->add('password', 'password', array('required' => false));
}
public function getName()
{
return 'user';
}
public function getDefaultOptions(array $options)
{
return array(
'data_class' => 'Trade\TradeBundle\Entity\User'
);
}
}
这是我的表格:
{% if error %}
<div class="alert alert-error">{{ error }}</div>
{% endif %}
<form action="{{ path('account_signin_check') }}" method="post" class="form-inline" novalidate>
<table class="table">
<tr>
<td style="width: 120px;">{{ form_label(form.username) }} <span class="required">*</span></td>
<td style="width: 220px;">{{ form_widget(form.username, { 'attr': {'placeholder': 'Username'} }) }}</td>
<td class="form-error" id="email_error">{{ form_errors(form.username) }}</td>
</tr>
<tr>
<td>{{ form_label(form.password) }} <span class="required">*</span></td>
<td>{{ form_widget(form.password, { 'attr': {'placeholder': 'Password'} }) }}</td>
<td class="form-error" id="password_error">{{ form_errors(form.password) }}</td>
</tr>
<tr>
<td colspan="2" style="text-align: right;">
{{ form_rest(form) }}
<input type="reset" value="Cancel" class="btn" />
<input type="submit" value="Sign in" class="btn btn-danger" />
</td>
<td> </td>
</tr>
</table>
</form>
当我尝试登录时,会显示BadCredentialsException。我不知道为什么。我想我根据Symfony的文档做了一切正确的请帮助。
答案 0 :(得分:1)
尝试使用像_username和_password这样的输入名称,或者在security.yml中尝试将其放在secured_area下
username_parameter: username
password_parameter: password
也许它可以帮到你!
答案 1 :(得分:0)
这已经很久了,但我希望我的回答可以帮助别人。
我试图将表单组件的使用与安全组件的使用完全相同。
不幸的是,这是不可能的,因为安全组件在调用login_check函数时依赖于输入形式“名称”参数(名称的html定义) _username 和 _password 。不能使用表单组件定义(无法定义输入元素的此可选参数)。
使用
为元素命名时- &gt;添加( 'MY_NAME',...
实际上这是被通知的元素的id参数,而不是“name”参数。 buidlForm函数给出的“name”将是“somename [my_name]”(其中somename是Form类的getName()函数返回的值),根据安全组件的要求,它不能是“_username”。
也许一个解决方法是在安全定义文件中将username_parameter定义为“somename [my_name]”,以便组件查找它,但我甚至没有尝试过这个,因为这是一个非常讨厌的黑客。
编辑: 实际上我用于另一个问题的另一个解决方法是在Form类的getName()函数中返回一个空字符串,因此我们得到:“my_name”作为输入元素属性而不是“somename [my_name]”。 所以也许我们可以尝试将“_username”和“_password”值赋予name属性(尚未尝试过)。