2013-05-10 82 views
2

我在使用Silex和安全服務時遇到了一些小問題。成功登錄後Silex不直接登錄

當用戶輸入他的數據(正確)到我的登錄表單中時,它不會被重定向到應用程序url。他仍然在同一頁面中,並且在登錄表單頁面中進行調試時沒有任何安全提供程序表明他已通過身份驗證。但是,在「成功登錄」之後,如果我直接在瀏覽器中輸入網址,則可以訪問,因爲我已通過身份驗證。事情是這樣的過程:

首頁 - >登錄檢查(登錄OK) - >主頁(未經認證) - > /應用程序(認證)

我想它直接重定向到如果/應用登錄工作正常,並理解爲什麼在我的主頁上,即使成功登錄後,安全提供程序仍然說我沒有通過身份驗證。

我寫的跟隨着代碼:

的index.php

<?php 

use Symfony\Component\HttpFoundation\Request; 
use Symfony\Component\Validator\Constraints as Assert; 

require_once __DIR__.'/../vendor/autoload.php'; 

$app = new Silex\Application(); 

/** 
* App Registrations & Debug Setting 
*/ 

$app 
    ->register(new Silex\Provider\TwigServiceProvider(), array('twig.path' => __DIR__.'/../views')) 
    ->register(new Silex\Provider\UrlGeneratorServiceProvider()) 
    ->register(new Silex\Provider\SessionServiceProvider()) 
    ->register(new Silex\Provider\FormServiceProvider()) 
    ->register(new Silex\Provider\ValidatorServiceProvider()) 
    ->register(new Silex\Provider\TranslationServiceProvider(), array(
     'translator.messages' => array(), 
    )) 
    ->register(new Silex\Provider\DoctrineServiceProvider(), array(
     'db.options' => array(
      'driver' => 'pdo_mysql', 
      'dbname' => 'pomodesk', 
      'host'  => 'localhost', 
      'user'  => 'root', 
      'password' => 'root' 
     ) 
    )) 
    ->register(new Silex\Provider\SecurityServiceProvider(), array(
     'security.firewalls' => array(
      'app' => array(
       'pattern' => '^/app', 
       'http' => true, 
       'form' => array('login_path' => '/', 'check_path' => '/app/login_check'), 
       'logout' => array('logout_path' => '/app/logout'), 
       'anonymous' => false, 
       'users' => $app->share(function() use ($app) { 
        return new Pomodesk\Provider\UserProvider($app['db']); 
       }) 
      ), 
     ), 
     'security.access_rules' => array(
      array('^/app', 'ROLE_USER') 
     ) 
    )); 

$app['debug'] = true; 

/** 
* App Routes 
*/ 

$app->get('/', function(Request $request) use ($app) { 

    $form = $app['form.factory'] 
     ->createBuilder('form') 
     ->add('name', 'text') 
     ->add('email', 'text') 
     ->add('password', 'password') 
     ->getForm(); 

    if ('POST' == $request->getMethod()) { 
     $form->bind($request); 

     $data = $form->getData(); 

     $constraint = new Assert\Collection(array(
      'name'  => array(new Assert\Length(array('min' => 5)), new Assert\NotBlank()), 
      'email' => new Assert\Email(), 
      'password' => array(new Assert\Length(array('min' => 6)), new Assert\NotBlank()) 
     )); 

     $errors = $app['validator']->validateValue($data, $constraint); 

     $userProvider = new Pomodesk\Provider\UserProvider($app['db']); 

     try { 
      $duplicated = $userProvider->loadUserByUsername($data['email']); 
     } catch (Exception $e) { 
      $duplicated = false; 
     } 

     if ($form->isValid() && count($errors) < 1 && !$duplicated) { 
      $user = new \Symfony\Component\Security\Core\User\User($data['email'], '', array('ROLE_USER')); 

      $encoder = $app['security.encoder_factory']->getEncoder($user); 

      $insertion = $app['db']->insert(
       'user', 
       array(
        'email' => $data['email'], 
        'name'  => $data['name'], 
        'password' => $encoder->encodePassword($data['password'], $user->getSalt()), 
        'roles' => 'ROLE_USER' 
       ) 
      ); 

      return $app['twig']->render('home.html.twig', array(
       'username' => $data['email'], 
       'signup' => true 
      )); 
     } 

     return $app['twig']->render('home.html.twig', array(
      'username' => $data['email'], 
      'signup' => true 
     )); 
    } 

    return $app['twig']->render('home.html.twig', array(
     'error'   => $app['security.last_error']($request), 
     'last_username' => $app['session']->get('_security.last_username'), 
     'form'   => $form->createView() 
    )); 
}) 
->method('GET|POST') 
->bind('home'); 

$app->get('/app', function() use ($app) { 

    $app['app_js'] = $app['twig']->render('script.js.twig'); 
    $data = array(); 

    return $app['twig']->render('app.html.twig', $data); 
}) 
->bind('app_home'); 

$app->run(); 

UserProvider.php

<?php 

namespace Pomodesk\Provider; 

use Symfony\Component\Security\Core\User\UserProviderInterface; 
use Symfony\Component\Security\Core\User\UserInterface; 
use Symfony\Component\Security\Core\User\User; 
use Symfony\Component\Security\Core\Exception\UnsupportedUserException; 
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException; 
use Doctrine\DBAL\Connection; 

class UserProvider implements UserProviderInterface 
{ 
    private $conn; 

    public function __construct(Connection $conn) 
    { 
     $this->conn = $conn; 
    } 

    public function loadUserByUsername($username) 
    { 
     $stmt = $this->conn->executeQuery('SELECT * FROM user WHERE email = ?', array(strtolower($username))); 

     if (!$user = $stmt->fetch()) { 
      throw new UsernameNotFoundException(sprintf('Email "%s" does not exist.', $username)); 
     } 

     return new User($user['email'], $user['password'], explode(',', $user['roles']), true, true, true, true); 
    } 

    public function refreshUser(UserInterface $user) 
    { 
     if (!$user instanceof User) { 
      throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', get_class($user))); 
     } 

     return $this->loadUserByUsername($user->getUsername()); 
    } 

    public function supportsClass($class) 
    { 
     return $class === 'Symfony\Component\Security\Core\User\User'; 
    } 
} 

非常感謝!

回答

5

更改您的代碼如下所示:

->register(new Silex\Provider\SecurityServiceProvider(), array(
      'security.firewalls' => array(
       'app' => array(
        'pattern' => '^/', 
        'http' => true, 
        'form' => array('login_path' => '/', 'check_path' => '/app/login_check'), 
        'logout' => array('logout_path' => '/app/logout'), 
        'anonymous' => true, 
        'users' => $app->share(function() use ($app) { 
         return new Pomodesk\Provider\UserProvider($app['db']); 
        }) 
       ), 
      ), 
      'security.access_rules' => array(
       array('^/app', 'ROLE_USER') 
      ) 
     )); 

允許匿名用戶在防火牆,只是保護與訪問規則/應用程序路徑。如果你不這樣做,你會遇到問題的上下文,假設你想要一個自定義菜單,如果用戶在你的應用程序的所有頁面上登錄,即使那些沒有安全的,你將無法做到這一點,如果你不會在所有網站上分享安全上下文。

這些都是一些可以在形式陣列中使用的選項,根據symfony的DOC:

  # login success redirecting options (read further below) 
      always_use_default_target_path: false 
      default_target_path:   /
      target_path_parameter:   _target_path 
      use_referer:     false 

​​

所以重定向可以通過一個隱藏的輸入登錄表單,或設置來處理default_target_path

'form' => array(
    'login_path' =>      '/', 
    'check_path' =>      '/app/login_check', 
    'default_target_path' =>   '/app', 
    'always_use_default_target_path' => true 
), 
+0

非常感謝! – joaobarbosa 2013-05-13 12:37:46

+0

嗨你有一個GitHub的登錄?我還需要一個登錄過程,我可以有你的工作副本,所以我可以嘗試在我的本地? – knives22 2015-12-22 01:46:03