PdoSessionHandler FOSUserBundle Login



我已经实现了将会话保存到数据库的教程,但问题是在我将其应用到应用程序后登录就不起作用了,它似乎没有得到基于以下日志的实体:

〔2014-02-26 05:47:10〕请求。信息:匹配的路线";fos_user_security_check";(参数:"_controller":"FOS\UserBundle\controller\SecurityController::checkAction","_route":"FOS_user_security_check")[][]

〔2014-02-26 05:47:10〕事件。DEBUG:通知事件";kernel.request";听众";Symfony\Component\HttpKernel\EventListener\LocalListener::onKernelRequest"。[][]

〔2014-02-26 05:47:10〕事件。DEBUG:通知事件";kernel.request";听众";Symfony\Component\Security\Http\Firewall::onKernelRequest"。[][]

〔2014-02-26 05:47:10〕安全。信息:身份验证请求失败:无效的CSRF令牌。[][]

〔2014-02-26 05:47:10〕安全。调试:重定向到/login[][]

与默认的会话处理程序相反,它登录得很好:

〔2014-02-26 07:10:07〕请求。信息:匹配的路线";fos_user_security_check";(参数:"_controller":"FOS\UserBundle\controller\SecurityController::checkAction","_route":"FOS_user_security_check")[][]

〔2014-02-26 07:10:07〕事件。DEBUG:通知事件";kernel.request";听众";Symfony\Component\HttpKernel\EventListener\LocaleListener::onKernelRequest"。[][]

〔2014-02-26 07:10:07〕事件。DEBUG:通知事件";kernel.request";听众";Symfony\Component\Security\Http\Firewall::onKernelRequest"。[][]

〔2014-02-26 07:10:07〕学说。调试:选择t0.username AS用户名1,t0.username_canonical AS用户名_canonical2,t0.email AS email3,t0.email_canonicl AS email_canonicl4,t0.enabled AS enabled5,t0.salt AS salt6,t0.password AS password7,t0.last_login AS last_login8,t0.locked AS locked9,t0.expired AS expired10,t0.eexpires_at AS expires_at11,t0.confirmation_token AS confirmation_token12,t0.password_requested_at AS password_requestd_at13,t0.roles AS roles14,t0.credentials_expired AS credentials_expired15,t0.credentials_eexpire_at AS credentials expire_at16,t0.id AS id17,t0.first_name AS first_name18,t0.last_name AS last_name19,t0.date_created AS date_created20 FROM Users t0 WHERE t0.username_canonic=?极限1["rainesedric23"][]

〔2014-02-26 07:10:07〕安全。INFO:用户";雷恩塞德里克23";已成功通过身份验证[][]

正如您所看到的,日志显示与默认会话处理程序相比,PdoSessionHandler没有与条令交互。我还注意到,在表单提交后,侦听器无法获得导致身份验证请求失败的CSRF令牌。

更新:

这是没有CSRF令牌的日志,它对用户进行身份验证,但在离开页面后,它在数据库中写入另一个会话,使下一页用户令牌再次匿名:

〔2014-02-26 07:39:59〕安全。INFO:用户";雷恩塞德里克23";已成功通过身份验证[][]

〔2014-02-26 07:39:59〕安全。调试:从会话[][]读取SecurityContext

〔2014-02-26 07:39:59〕安全。调试:从用户提供程序重新加载用户。[][]

〔2014-02-26 07:39:59〕学说。调试:选择t0.username AS用户名1,t0.username_canonical AS用户名_canonical2,t0.email AS email3,t0.email_canonicl AS email_canonicl4,t0.enabled AS enabled5,t0.salt AS salt6,t0.password AS password7,t0.last_login AS last_login8,t0.locked AS locked9,t0.expired AS expired10,t0.eexpires_at AS expires_at11,t0.confirmation_token AS confirmation_token12,t0.password_requested_at AS password_requestd_at13,t0.roles AS roles14,t0.credentials_expired AS credentials_expired15,t0.credentials_eexpire_at AS credentials expire_at16,t0.id AS id17,t0.first_name AS first_name18,t0.last_name AS last_name19,t0.date_created AS date_created20 FROM Users t0 WHERE t0.id=?极限1[7][]

〔2014-02-26 07:39:59〕安全。调试:用户名;雷恩塞德里克23";已从用户提供程序重新加载。[][]

〔2014-02-26 07:40:00〕安全。调试:在会话[][]中写入SecurityContext

〔2014-02-26 07:40:00〕安全。信息:使用匿名令牌[][]填充SecurityContext

〔2014-02-26 07:40:00〕安全。调试:访问被拒绝(用户未完全验证)

〔2014-02-26 07:40:00〕安全。调试:调用身份验证入口点[][]

关于如何解决它有什么想法吗?谢谢!~

多亏了Daniel15,我在捆绑包中创建了一个customPdoSessionHandler,找到了一个解决方案(我已经调整了一些代码,以便能够在Symfony2中使用它),我已经将PdoSessionHandler作为我的customPdoSessionHandler 的基本处理程序

<?php
namespace foobarBundleHandler;
use SymfonyComponentHttpFoundationSessionStorageHandlerPdoSessionHandler as baseHandler;
/**
* PDO Session Handler
* @author Daniel15 <dan.cx>
*
* This class is actually static, but since PHP doesn't support static classes, abstract is close
* enough. You do not instantiate the class; you just call the static "init" method.
*/
class CustomPdoSessionHandler extends baseHandler {
private static $db;
private static $oldData;
private $pdo;
private $dbOptions;
public function __construct(PDO $pdo, array $dbOptions = array())
{
if (!array_key_exists('db_table', $dbOptions)) {
throw new InvalidArgumentException('You must provide the "db_table" option for a PdoSessionStorage.');
}
if (PDO::ERRMODE_EXCEPTION !== $pdo->getAttribute(PDO::ATTR_ERRMODE)) {
throw new InvalidArgumentException(sprintf('"%s" requires PDO error mode attribute be set to throw Exceptions (i.e. $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION))', __CLASS__));
}
$this->pdo = $pdo;
$this->dbOptions = array_merge(array(
'db_id_col'   => 'session_id',
'db_data_col' => 'data',
'db_time_col' => 'last_activity',
), $dbOptions);
}

/**
* Session open handler
* @param string Path to save session to
* @param string Name of the session
*/
public function open($save_path, $session_name) {
// Nothing
return true;
}
/**
* Session close handler
*/
public function close() {
// Nothing
return true;
}
/**
* Session load handler. Load the session
* @param string Session ID
*/
public function read($session_id) {
// Load Table from the database
$dbTable   = $this->dbOptions['db_table'];
$dbDataCol = $this->dbOptions['db_data_col'];
$dbIdCol   = $this->dbOptions['db_id_col'];
// Load the session data from the database
$query = $this->pdo->prepare("
SELECT $dbDataCol
FROM $dbTable
WHERE $dbIdCol = :session_id");
$query->execute(array(':session_id' => $session_id));
return $query->fetchColumn();
}
/**
* Session save handler. Save the session
* @param string Session ID
* @param string Data to save to session
*/
public function write($session_id, $data) {
//load table form the database
$dbTable   = $this->dbOptions['db_table'];
$dbDataCol = $this->dbOptions['db_data_col'];
$dbIdCol   = $this->dbOptions['db_id_col'];
$dbTimeCol = $this->dbOptions['db_time_col'];
/* Try to update the existing session. If we can't find one, then create a new one. If you
* are using MySQL, this can be done in a single INSERT statment via INSERT ... ON 
* DUPLICATE KEY UPDATE. Remove the UPDATE and edit the INSERT to do it this way.
* See http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
*
* This does two queries so you can use any DBMS.
*/
$query = $this->pdo->prepare("
UPDATE $dbTable
SET $dbDataCol = :data, last_activity = :last_activity
WHERE $dbIdCol = :session_id");
$query->execute(array(
":session_id" => $session_id,
":data" => $data,
"$dbTimeCol" => time()));
// No session to update? Create a new one
if ($query->rowCount() == 0) {
$query = $this->pdo
->prepare('
INSERT INTO sessions
(session_id, data, last_activity)
VALUES
(:session_id, :data, :last_activity)')
->execute(array(
':session_id' => $session_id,
':data' => $data,
'last_activity' => time())
);
}
}
/**
* Session delete handler. Delete the session from the database
* @param string Session ID
*/
public function destroy($session_id) {
//Load Table from the database
$dbTable   = $this->dbOptions['db_table'];
$dbIdCol   = $this->dbOptions['db_id_col'];
$this->pdo
->prepare("
DELETE FROM $dbTable
WHERE $dbIdCol = :session_id")
->execute(array(':session_id' => $session_id));
}
/**
* Session garbage collector. Delete any old expired sessions
* @param int How many seconds do sessions last for?
*/
public function gc($lifetime) {
//Load Table from the database
$dbTable   = $this->dbOptions['db_table'];
$dbTimeCol = $this->dbOptions['db_time_col'];
$this->pdo
->prepare("
DELETE FROM $dbTable
WHERE $dbTimeCol < :min_time")
->execute(array(':min_time' => time() - $lifetime));
}
}

并修改了config.yml:中的类

framework:
session:
handler_id:  session.handler.pdo
services:
pdo:
class: PDO
arguments:
dsn:      "mysql:dbname=dev_reporting_system"
user:     root
password: null
calls:
- [setAttribute, [3, 2]] # PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION
session.handler.pdo:
class:     foorbarBundleHandlerCustomPdoSessionHandler
arguments: ["@pdo", "%pdo.db_options%"]  

希望它能帮助其他人:D

相关内容

  • 没有找到相关文章

最新更新