2016-07-28 31 views
1

我有一個非常奇怪的問題,我不明白。我很確定我錯過了配置中的某些東西,所以我希望有人能幫助我。只登錄了一個請求,刷新後註銷

我正試圖在Symfony中創建一個簡單的登錄表單。當我登錄時,我看到經過身份驗證的用戶確實是我剛纔嘗試登錄的用戶。但是,當我刷新頁面或瀏覽到其他頁面時,用戶會註銷並重新導向登錄頁面。我不明白爲什麼我總是退出。

我的用戶等級:

<?php namespace AppBundle\Entity; 

use Doctrine\ORM\Mapping as ORM; 
use Symfony\Component\Security\Core\User\UserInterface; 

/** 
* @ORM\Entity 
*/ 
class User implements UserInterface 
{ 
    /** 
    * @ORM\Column(type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

    /** 
    * @ORM\Column(type="string", length=100) 
    */ 
    public $email; 

    /** 
    * @ORM\Column(type="string", length=64) 
    */ 
    private $password; 

    public function getUsername() 
    { 
     return $this->email; 
    } 

    public function getRoles() 
    { 
     return ['ROLE_USER']; 
    } 

    public function getPassword() 
    { 
     return $this->password; 
    } 

    public function getSalt() 
    { 
     return null; 
    } 

    public function eraseCredentials() 
    { 
     return null; 
    } 

    /** 
    * Get id 
    * 
    * @return integer 
    */ 
    public function getId() 
    { 
     return $this->id; 
    } 

    /** 
    * Set email 
    * 
    * @param string $email 
    * 
    * @return User 
    */ 
    public function setEmail($email) 
    { 
     $this->email = $email; 

     return $this; 
    } 


    /** 
    * Set password 
    * 
    * @param string $password 
    * 
    * @return User 
    */ 
    public function setPassword($password) 
    { 
     $this->password = $password; 

     return $this; 
    } 
} 

我的後衛身份驗證:

<?php namespace AppBundle\Authentication; 
use Symfony\Component\Security\Guard\AbstractGuardAuthenticator; 
use Symfony\Component\Security\Guard\GuardAuthenticatorInterface; 
use Symfony\Component\Security\Core\User\UserInterface; 
use Symfony\Component\Security\Core\User\UserProviderInterface; 
use Symfony\Component\Security\Core\Exception\AuthenticationException; 
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; 
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface; 
use Symfony\Component\Routing\RouterInterface; 
use Symfony\Component\HttpFoundation\Request; 
use Symfony\Component\HttpFoundation\RedirectResponse; 
use Doctrine\ORM\EntityManagerInterface; 

class Authenticator extends AbstractGuardAuthenticator implements GuardAuthenticatorInterface 
{ 
    /** 
    * @var \Symfony\Component\Routing\RouterInterface 
    */ 
    private $router; 

    private $em; 

    private $encoder; 


    public function __construct(RouterInterface $router, EntityManagerInterface $entityManager, UserPasswordEncoderInterface $passwordEncoder) 
    { 
     $this->router = $router; 
     $this->em = $entityManager; 
     $this->encoder = $passwordEncoder; 
    } 

    /** 
    * Get the authentication credentials from the request and return them 
    * as any type (e.g. an associate array). If you return null, authentication 
    * will be skipped. 
    * 
    * Whatever value you return here will be passed to getUser() and checkCredentials() 
    * 
    * For example, for a form login, you might: 
    * 
    *  if ($request->request->has('_username')) { 
    *   return array(
    *    'username' => $request->request->get('_username'), 
    *    'password' => $request->request->get('_password'), 
    *   ); 
    *  } else { 
    *   return; 
    *  } 
    * 
    * Or for an API token that's on a header, you might use: 
    * 
    *  return array('api_key' => $request->headers->get('X-API-TOKEN')); 
    * 
    * @param Request $request 
    * 
    * @return mixed|null 
    */ 
    public function getCredentials(Request $request) 
    { 
     return [ 
      'username' => $request->request->get('username'), 
      'password' => $request->request->get('password') 
     ]; 
    } 

    public function start(Request $request, AuthenticationException $authException = null) 
    { 
     $url = $this->router->generate('login'); 
     return new RedirectResponse($url); 
    } 

    /** 
    * Return a UserInterface object based on the credentials. 
    * 
    * The *credentials* are the return value from getCredentials() 
    * 
    * You may throw an AuthenticationException if you wish. If you return 
    * null, then a UsernameNotFoundException is thrown for you. 
    * 
    * @param mixed     $credentials 
    * @param UserProviderInterface $userProvider 
    * 
    * @throws AuthenticationException 
    * 
    * @return UserInterface|null 
    */ 
    public function getUser($credentials, UserProviderInterface $userProvider) 
    { 
     $user = $this->em->getRepository('AppBundle:User') 
      ->findOneBy(array(
       'email' => $credentials['username'])); 

     return $user; 
    } 

    /** 
    * Returns true if the credentials are valid. 
    * 
    * If any value other than true is returned, authentication will 
    * fail. You may also throw an AuthenticationException if you wish 
    * to cause authentication to fail. 
    * 
    * The *credentials* are the return value from getCredentials() 
    * 
    * @param mixed   $credentials 
    * @param UserInterface $user 
    * 
    * @return bool 
    * 
    * @throws AuthenticationException 
    */ 
    public function checkCredentials($credentials, UserInterface $user) 
    { 
     $plainPassword = $credentials['password']; 


     if ($this->encoder->isPasswordValid($user, $plainPassword)) 
     { 
      return true; 
     } 

     return false; 
    } 

    /** 
    * Called when authentication executed, but failed (e.g. wrong username password). 
    * 
    * This should return the Response sent back to the user, like a 
    * RedirectResponse to the login page or a 403 response. 
    * 
    * If you return null, the request will continue, but the user will 
    * not be authenticated. This is probably not what you want to do. 
    * 
    * @param Request     $request 
    * @param AuthenticationException $exception 
    * 
    * @return Response|null 
    */ 
    public function onAuthenticationFailure(Request $request, AuthenticationException $exception) 
    { 
    } 

    /** 
    * Called when authentication executed and was successful! 
    * 
    * This should return the Response sent back to the user, like a 
    * RedirectResponse to the last page they visited. 
    * 
    * If you return null, the current request will continue, and the user 
    * will be authenticated. This makes sense, for example, with an API. 
    * 
    * @param Request  $request 
    * @param TokenInterface $token 
    * @param string   $providerKey The provider (i.e. firewall) key 
    * 
    * @return Response|null 
    */ 
    public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey) 
    { 
     return null; 
    } 

    /** 
    * Does this method support remember me cookies? 
    * 
    * Remember me cookie will be set if *all* of the following are met: 
    * A) This method returns true 
    * B) The remember_me key under your firewall is configured 
    * C) The "remember me" functionality is activated. This is usually 
    *  done by having a _remember_me checkbox in your form, but 
    *  can be configured by the "always_remember_me" and "remember_me_parameter" 
    *  parameters under the "remember_me" firewall key 
    * 
    * @return bool 
    */ 
    public function supportsRememberMe() 
    { 
     return false; 
    } 
} 

最後我security.yaml:

security: 
    encoders: 
     AppBundle\Entity\User: bcrypt 

    providers: 
     our_db_provider: 
      entity: 
       class: AppBundle:User 
       property: email 

    firewalls: 
     # disables authentication for assets and the profiler, adapt it according to your needs 
     dev: 
      pattern: ^/(_(profiler|wdt)|css|images|js)/ 
      security: false 
     secured_area: 
      anonymous: ~ 
      logout: 
       path: /logout 
       target: /login 
      guard: 
       authenticators: 
        - user_authenticator 

     main: 
      pattern: ^/login 
      form_login: ~ 
      provider: our_db_provider 

    access_control: 
     - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY } 
     - { path: ^/register, roles: IS_AUTHENTICATED_ANONYMOUSLY } 
     - { path: ^/, roles: ROLE_USER } 

我也檢查了會話目錄的權限和將其設置爲777.我看到一個新的會話文件被創建,但不知何故它不斷。

在此先感謝!

UPDATE:

我也看到,當我跟我的憑據登錄我得到登錄匿名。我不知道爲什麼。

回答

2

嘗試實現Serializable接口。 這需要在會話中存儲用戶信息。

/** @see \Serializable::serialize() */ 
public function serialize() 
{ 
    return serialize(array(
     $this->id, 
     $this->username, 
     $this->password, 
     // see section on salt below 
     // $this->salt, 
    )); 
} 

/** @see \Serializable::unserialize() */ 
public function unserialize($serialized) 
{ 
    list (
     $this->id, 
     $this->username, 
     $this->password, 
     // see section on salt below 
     // $this->salt 
    ) = unserialize($serialized); 
} 

如果不是唯一的問題,請考慮以下http://symfony.com/doc/current/security/entity_provider.html 步步

更新:你爲什麼寫自己的認證?也許嘗試使用默認的這可能也是問題。

+0

感謝您的幫助。它沒有解決這個問題,但是,當我設置一個「記住我」標記時,它實際上確實有效。從我所能看到的是,這確實是會議的一個問題。從會話中的安全令牌無法檢索用戶,但它可以從記住我的cookie中檢索它。我也寫我自己的認證,因爲我只是想知道這個東西是如何工作的:) –