我開始使用最新的穩定版本(2.6.1)開始一個新的Symfony2項目,並且我已經設置了最小的登錄和安全組件配置。但是,在處理/ login_check請求後,當用戶重定向回主頁時,一半的登錄嘗試似乎失敗。Symfony 2.6登錄隨機失敗
這就是日誌登錄失敗後顯示(箭頭雷強調):
request.INFO: Matched route "login_check" (parameters: "_route": "login_check") [] []
doctrine.DEBUG: SELECT t0.id AS id1, t0.username AS username2, t0.password AS password3, t0.nombre AS nombre4, t0.apellidos AS apellidos5, t0.email AS email6, t0.movil AS movil7, t0.ciudad AS ciudad8, t0.hospital AS hospital9, t0.cargo AS cargo10, t0.roles AS roles11, t0.created_at AS created_at12 FROM usuarios t0 WHERE t0.username = ? LIMIT 1 ["admin"] []
--> security.INFO: User "admin" has been authenticated successfully [] []
security.DEBUG: Write SecurityContext in the session [] []
request.INFO: Matched route "homepage" (parameters: "_controller": "AppBundle\Controller\DefaultController::indexAction", "_route": "homepage") [] []
--> security.INFO: Populated SecurityContext with an anonymous Token [] []
security.DEBUG: Write SecurityContext in the session [] []
正如你可以看到login_check過程實際上是在認證用戶成功,但是當它被重定向到另一個頁面系統以某種方式「忘記」它,就好像它實際上沒有將結果存儲在會話中一樣。當整個過程的工作日誌是這樣看:
request.INFO: Matched route "login_check" (parameters: "_route": "login_check") [] []
doctrine.DEBUG: SELECT t0.id AS id1, t0.username AS username2, t0.password AS password3, t0.nombre AS nombre4, t0.apellidos AS apellidos5, t0.email AS email6, t0.movil AS movil7, t0.ciudad AS ciudad8, t0.hospital AS hospital9, t0.cargo AS cargo10, t0.roles AS roles11, t0.created_at AS created_at12 FROM usuarios t0 WHERE t0.username = ? LIMIT 1 ["admin"] []
--> security.INFO: User "admin" has been authenticated successfully [] []
security.DEBUG: Write SecurityContext in the session [] []
request.INFO: Matched route "homepage" (parameters: "_controller": "AppBundle\Controller\DefaultController::indexAction", "_route": "homepage") [] []
--> security.DEBUG: Read SecurityContext from the session [] []
security.DEBUG: Reloading user from user provider. [] []
doctrine.DEBUG: SELECT t0.id AS id1, t0.username AS username2, t0.password AS password3, t0.nombre AS nombre4, t0.apellidos AS apellidos5, t0.email AS email6, t0.movil AS movil7, t0.ciudad AS ciudad8, t0.hospital AS hospital9, t0.cargo AS cargo10, t0.roles AS roles11, t0.created_at AS created_at12 FROM usuarios t0 WHERE t0.id = ? [1] []
--> security.DEBUG: Username "admin" was reloaded from user provider. [] []
security.DEBUG: Write SecurityContext in the session [] []
這是整個安裝我的時刻。我打賭它是在security.yml文件中配置錯誤或者錯誤(?),但我不知道還有什麼地方需要注意。
security.yml
security:
encoders:
AppBundle\Entity\Usuario: bcrypt
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
providers:
usuarios:
entity: { class: AppBundle\Entity\Usuario, property: username }
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
default:
pattern: ^/
anonymous: ~
form_login:
check_path: login_check
login_path: login
logout:
path: logout
target: homepage
access_control:
- { path: ^/$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/login$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/.*, roles: ROLE_USER }
的routing.yml
app:
resource: @AppBundle/Controller/
type: annotation
login_check:
path: /login_check
logout:
path: /logout
login.html.twig
{% extends 'base.html.twig' %}
{% block body %}
{% if error %}
<div>{{ error.message }}</div>
{% endif %}
<form action="{{ path('login_check') }}" method="post">
<label for="username">Nombre de usuario:</label>
<input type="text" id="username" name="_username" value="{{ last_username }}" />
<label for="password">Contraseña:</label>
<input type="password" id="password" name="_password" />
<input type="submit" name="login" value="Acceder" />
</form>
{% endblock %}
DefaultController.php
<?php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class DefaultController extends Controller
{
/**
* @Route("/", name="homepage")
*/
public function indexAction()
{
// Symfony dummy template that just shows 'Homepage.'
return $this->render('default/index.html.twig');
}
/**
* @Route("/login", name="login")
*/
public function loginAction()
{
$authUtils = $this->get('security.authentication_utils');
return $this->render('login/index.html.twig', array(
'last_username' => $authUtils->getLastUsername(),
'error' => $authUtils->getLastAuthenticationError(),
));
}
}
Usuario.php
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\AdvancedUserInterface;
/**
* @ORM\Table(name="usuarios")
* @ORM\Entity
*/
class Usuario implements AdvancedUserInterface
{
const ROLE_USER = 'ROLE_USER';
const ROLE_ADMIN = 'ROLE_ADMIN';
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="username", type="string", length=255, unique=true)
*/
private $username;
/**
* @var string
*
* @ORM\Column(name="password", type="string", length=60)
*/
private $password;
/**
* @var string
*
* @ORM\Column(name="nombre", type="string", length=255)
*/
private $nombre;
/**
* @var string
*
* @ORM\Column(name="apellidos", type="string", length=255)
*/
private $apellidos;
/**
* @var string
*
* @ORM\Column(name="email", type="string", length=255, unique=true)
*/
private $email;
/**
* @var string
*
* @ORM\Column(name="movil", type="string", length=255)
*/
private $movil;
/**
* @var string
*
* @ORM\Column(name="ciudad", type="string", length=255)
*/
private $ciudad;
/**
* @var string
*
* @ORM\Column(name="hospital", type="string", length=255)
*/
private $hospital;
/**
* @var string
*
* @ORM\Column(name="cargo", type="string", length=255)
*/
private $cargo;
/**
* @var string
*
* @ORM\Column(name="roles", type="simple_array", length=255)
*/
private $roles;
/**
* @var \DateTime
*
* @ORM\Column(name="created_at", type="datetime")
*/
private $createdAt;
public function __construct()
{
$this->roles = [self::ROLE_USER];
$this->createdAt = new \DateTime();
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
// ... An awful lot of generic getters and setters
// Plus the mandatory AdvancedUserInterface methods:
/**
* @inheritdoc
*/
public function getUsername()
{
return $this->username;
}
/**
* @inheritdoc
*/
public function getPassword()
{
return $this->password;
}
/**
* @inheritdoc
*/
public function isAccountNonExpired()
{
return true;
}
/**
* @inheritdoc
*/
public function isAccountNonLocked()
{
return true;
}
/**
* @inheritdoc
*/
public function isCredentialsNonExpired()
{
return true;
}
/**
* @inheritdoc
*/
public function isEnabled()
{
return true;
}
/**
* @inheritdoc
*/
public function getSalt()
{
return null; // I'm using the bcrypt encoder
}
/**
* @inheritdoc
*/
public function eraseCredentials()
{
$this->password = null;
}
}