Я пытался реализовать все в соответствии с документацией Symfony, но, похоже, аутентификация не работает вообще. Посмотрите, что именно я сделал:
security.yml
security:
encoders:
AppBundle\Entity\StUser:
algorithm: bcrypt
cost: 12
providers:
our_db_provider:
entity:
class: AppBundle:Entity:StUser
firewalls:
user_secured_area:
pattern: ^/([a-z]{2})/account
provider: our_db_provider
form_login:
login_path: login
check_path: login_check
csrf_token_generator: security.csrf.token_manager
default:
anonymous: ~
http_basic: ~
Объект StUser.php
namespace AppBundle\Entity;
class StUser implements UserInterface
{
private $id;
private $firstName;
private $lastName;
private $password;
private $username;
private $isAdmin = '0';
private $confirmed;
private $created = 'CURRENT_TIMESTAMP';
private $status = '1';
public function getId()
{
return $this->id;
}
public function setFirstName($firstName)
{
$this->firstName = $firstName;
return $this;
}
public function getFirstName()
{
return $this->firstName;
}
public function setLastName($lastName)
{
$this->lastName = $lastName;
return $this;
}
public function getLastName()
{
return $this->lastName;
}
public function setPassword($password)
{
$this->password = $password;
return $this;
}
public function getPassword()
{
return $this->password;
}
public function setUsername($username)
{
$this->username = $username;
return $this;
}
public function getUsername()
{
return $this->username;
}
public function setIsAdmin($isAdmin)
{
$this->isAdmin = $isAdmin;
return $this;
}
public function getIsAdmin()
{
return $this->isAdmin;
}
public function setConfirmed($confirmed)
{
$this->confirmed = $confirmed;
return $this;
}
public function getConfirmed()
{
return $this->confirmed;
}
public function setCreated($created)
{
$this->created = $created;
return $this;
}
public function getCreated()
{
return $this->created;
}
public function setStatus($status)
{
$this->status = $status;
return $this;
}
public function getStatus()
{
return $this->status;
}
/* ==== Additional =================================================== */
public function __construct($username, $password, $salt, array $roles)
{
$this->username = $username;
$this->password = $password;
/* $this->salt = $salt; */
/* $this->roles = $roles; */
}
public function getRoles()
{
return null;
}
public function getSalt()
{
return null;
}
public function eraseCredentials()
{
}
}
Репозиторий UserRepository.php:
namespace AppBundle\Repository;
use Symfony\Bridge\Doctrine\Security\User\UserLoaderInterface;
use Doctrine\ORM\EntityRepository;
class UserRepository extends EntityRepository implements UserLoaderInterface
{
public function loadUserByUsername($username)
{
return $this->createQueryBuilder('u')
->where('u.username = :username OR u.email = :email')
->setParameter('username', $username)
->setParameter('email', $username)
->getQuery()
->getOneOrNullResult();
}
}
AccountController.php
namespace AccountBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
class AccountController extends Controller
{
/**
* @Route("{_lang}/login", name="login", requirements={"_lang": "pl"})
*/
public function loginAction(Request $request, $_lang = '')
{
$helper = $this->get('security.authentication_utils');
$error = $helper->getLastAuthenticationError();
var_dump( $error );
return $this->render('account/login.html.twig', array(
'projects' => "",
'lang' => "pl",
'allLangs' => "",
'mainLang' => "",
'meta_title' => "test",
'meta_description' => "",
'meta_keywords' => "",
'meta_robots' => "",
'image_src' => "",
'social_title' => "",
'social_description' => "",
'social_url' => "",
'aaaa' => $helper,
/* 'last_username' => $lastUsername,
'error' => $error, */
));
}
}
login.html.twig view
{% block body %}
<form action="{{ path('login', {'_lang': lang}) }}" method="post">
<label for="username">Username:</label>
<input type="text" id="username" name="_username" value="" />
<label for="password">Password:</label>
<input type="password" id="password" name="_password" />
<input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}">
<button type="submit">login</button>
</form>
{% endblock %}
И ничего не происходит, $ helper и $ error пустые / нулевые, я ничего не могу найти в логах. Что я пропустил. Заранее спасибо.
В вашем security.yml вам нужно добавить анонимный ключ со значением по умолчанию и исправить поставщик ключ:
security.yml
security:
encoders:
AppBundle\Entity\StUser:
algorithm: bcrypt
cost: 12
providers:
our_db_provider:
entity:
class: AppBundle:StUser # not necessary to put 'Entity' here if your entities are in the Entity Folder
firewalls:
user_secured_area:
anonymous: ~
pattern: ^/([a-z]{2})/account
provider: our_db_provider
form_login:
login_path: login
check_path: login_check
csrf_token_generator: security.csrf.token_manager
Далее в вашем AccountController файл, почему вы не используете специальный параметр маршрутизации _locale ? Пожалуйста прочтите это : Специальные параметры маршрутизации.
Затем вы добавляете к вашим маршрутам параметр locale следующим образом:
AccountController.php
namespace AccountBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
class AccountController extends Controller
{
/**
* @Route("/{_locale}/login", name="login", requirements={"_locale": "pl"})
*/
public function loginAction(Request $request, $_lang = '')
{
$helper = $this->get('security.authentication_utils');
$error = $helper->getLastAuthenticationError();
var_dump( $error );
return $this->render('account/login.html.twig', array(
'projects' => "",
'lang' => "pl",
'allLangs' => "",
'mainLang' => "",
'meta_title' => "test",
'meta_description' => "",
'meta_keywords' => "",
'meta_robots' => "",
'image_src' => "",
'social_title' => "",
'social_description' => "",
'social_url' => "",
'aaaa' => $helper,
/* 'last_username' => $lastUsername,
'error' => $error, */
));
}
}
Я не знаю, какую стратегию отображения сущностей вы используете. Аннотация или XML?
Взгляните на это (из документации):
Не забудьте добавить класс репозитория в определение соответствия вашей сущности.
Я попробовал это, но безуспешно. Похоже, что любой пользовательский код никогда не вызывается.
Я обновил security.yml (когда я установил анонимный: ~, тогда он позволяет пользователям открывать для примера страницу аккаунта без авторизации):
security:
encoders:
AppBundle\Entity\StUser:
algorithm: bcrypt
cost: 12
providers:
our_db_provider:
entity:
class: AppBundle:StUser
firewalls:
user_secured_area:
pattern: ^/([a-z]{2})/account
# anonymous: ~
provider: our_db_provider
form_login:
login_path: login
check_path: login_check
csrf_token_generator: security.csrf.token_manager
default:
anonymous: ~
http_basic: ~
а также я обновил сущность пользователя:
StUser.orm.yml объект:
AppBundle\Entity\StUser:
type: entity
table: st_user
repositoryClass: AppBundle\Repository\UserRepository
indexes:
status_username_password:
columns:
- status
- username
- password
status_is_admin_username_password:
columns:
- status
- is_admin
- username
- password
id:
id:
type: integer
nullable: false
options:
unsigned: false
id: true
generator:
strategy: IDENTITY
fields:
firstName:
type: string
nullable: true
length: 255
options:
fixed: false
column: first_name
lastName:
type: string
nullable: true
length: 255
options:
fixed: false
column: last_name
password:
type: string
nullable: true
length: 255
options:
fixed: false
username:
type: string
nullable: true
length: 255
options:
fixed: false
isAdmin:
type: boolean
nullable: false
options:
default: '0'
column: is_admin
confirmed:
type: datetime
nullable: true
created:
type: datetime
nullable: false
options:
default: CURRENT_TIMESTAMP
status:
type: boolean
nullable: false
options:
default: '0'
lifecycleCallbacks: { }