[英]User still Anonymous after successful login Symfony 4
所以我創建了一個傳統的登錄表單。 成功登錄后,它重定向到我的儀表板,然后重定向回登錄。 檢查后,用戶是匿名的,並通過身份驗證。 我還能夠將用戶轉儲到我的自定義提供程序上。 我懷疑,Symfony 不會在會話中保存它。 為什么呢?
這是我到目前為止所做的:
安全.yml:
security:
encoders:
App\Entity\User:
algorithm: bcrypt
providers:
user_provider:
id: App\Security\UserProvider
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: ~
form_login:
login_path: security_login
check_path: security_login
default_target_path: dashboard
# activate different ways to authenticate
# http_basic: ~
# https://symfony.com/doc/current/security.html#a-configuring-how-your-users-will-authenticate
# form_login: ~
# https://symfony.com/doc/current/security/form_login_setup.html
access_control:
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/, roles: ROLE_ADMIN }
role_hierarchy:
ROLE_SUPER_ADMIN:
- ROLE_ALLOWED_TO_SWITCH
- ROLE_ADMIN
框架.yml
framework:
secret: '%env(APP_SECRET)%'
#default_locale: en
#csrf_protection: ~
#http_method_override: true
# Enables session support. Note that the session will ONLY be started if you read or write from it.
# Remove or comment this section to explicitly disable session support.
session:
# https://symfony.com/doc/current/reference/configuration/framework.html#handler-id
handler_id: session.handler.native_file
save_path: '%kernel.project_dir%/var/sessions/%kernel.environment%'
#esi: ~
#fragments: ~
php_errors:
log: true
cache:
# Put the unique name of your app here: the prefix seed
# is used to compute stable namespaces for cache keys.
#prefix_seed: your_vendor_name/app_name
# The app cache caches to the filesystem by default.
# Other options include:
# Redis
#app: cache.adapter.redis
#default_redis_provider: redis://localhost
# APCu (not recommended with heavy random-write workloads as memory fragmentation can cause perf issues)
#app: cache.adapter.apcu
用戶提供者
class UserProvider implements UserProviderInterface
{
private $em;
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
}
public function loadUserByUsername($username)
{
$user = $this->em->getRepository(User::class)->loadByUsername($username);
if ($user) {
return $user;
}
throw new UsernameNotFoundException(
sprintf('Username "%s" does not exist.', $username)
);
}
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 User::class === $class;
}
}
用戶
use Symfony\Component\Security\Core\User\UserInterface;
/**
* @ORM\Entity()
* @ORM\Entity(repositoryClass="App\Repository\UserRepository")
* @UniqueEntity("email", message="Email is already taken.")
* @UniqueEntity("username", message="Username is already taken.")
*/
class User implements AdvancedUserInterface, EquatableInterface, \Serializable
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\Column(type="string", length=255)
* @Assert\NotBlank(message="Username must not be blank.")
*/
private $username;
/**
* @Assert\NotBlank(message="Password must not be blank.")
*/
private $plainPassword;
/**
* @ORM\Column(type="string", length=255)
*/
private $password;
/**
* @ORM\Column(type="string", length=255)
* @Assert\NotBlank(message="Email must not be blank.")
* @Assert\Email()
*/
private $email;
/**
* @ORM\Column(type="string", length=255)
* @Assert\NotBlank(message="First name must not be blank.")
*/
private $firstName;
/**
* @ORM\Column(type="string", length=255)
* @Assert\NotBlank(message="Last name must not be blank.")
*/
private $lastName;
/**
* @ORM\Column(type="json_array")
*/
private $roles;
public function __construct()
{
$this->roles = [];
}
public function setFirstName(string $firstName)
{
$this->firstName = $firstName;
return $this;
}
public function getFirstName(): ?string
{
return $this->firstName;
}
public function setLastName(string $lastName)
{
$this->lastName = $lastName;
return $this;
}
public function getLastName(): ?string
{
return $this->lastName;
}
public function setUsername(string $username): User
{
$this->username = $username;
return $this;
}
public function setEmail(string $email): User
{
$this->email = $email;
return $this;
}
public function getEmail(): ?string
{
return $this->email;
}
public function setPassword($password)
{
$this->password = $password;
return $this->password;
}
public function setPlainPassword($plainPassword) : User
{
$this->plainPassword = $plainPassword;
return $this;
}
public function getPlainPassword() : ?string
{
return $this->plainPassword;
}
public function setRoles(array $roles): User
{
$this->roles = $roles;
return $this;
}
// Overriden Methods
public function getPassword()
{
return $this->password;
}
public function getUsername()
{
return $this->username;
}
public function eraseCredentials()
{
}
public function isEqualTo(UserInterface $user)
{
if (!$user instanceof WebserviceUser) {
return false;
}
if ($this->password !== $user->getPassword()) {
return false;
}
if ($this->salt !== $user->getSalt()) {
return false;
}
if ($this->username !== $user->getUsername()) {
return false;
}
return true;
}
public function isAccountNonExpired()
{
return true;
}
public function isAccountNonLocked()
{
return true;
}
public function isCredentialsNonExpired()
{
return true;
}
public function isEnabled()
{
return true;
}
public function serialize()
{
return serialize(array(
$this->id,
$this->username,
$this->password,
$this->roles,
));
}
public function unserialize($serialized)
{
list (
$this->id,
$this->username,
$this->password,
$this->roles
) = unserialize($serialized);
}
public function getRoles()
{
$roles = $this->roles;
$roles[] = 'ROLE_USER';
return array_unique($roles);
}
public function getSalt()
{
return null;
}
}
謝謝!
注意:我將 docker 與 Nginx 和 PHP-FPM 圖像一起使用。
今天我自己也遇到了同樣的問題,並且臉部也有了類似的時刻。 就我而言,事實證明我們並未序列化要在AdvancedUserInterface
方法中使用的所有必需的User實體數據。
例如:
UserEntity
:
...
public function isEnabled ()
{
return (0 < $this->status);
}
public function serialize ()
{
return serialize(array(
$this->id,
$this->username,
$this->password,
// $this->status, <- this was missing and needed added
));
}
public function unserialize ($serialized)
{
list (
$this->id,
$this->username,
$this->password
//, $this->status <-- this was missing and needed added
) = unserialize($serialized, array ("allowed_classes" => false));
}
...
因為我們沒有使用$this->status
屬性來序列化該對象,所以使用未序列化的UserEntity
時, isEnabled()
方法失敗。 添加屬性並清除會話后,它又可以正常工作了。
這可能會對某人有所幫助,我在此上花了幾個小時,並且遇到了類似的問題..確保用戶序列化正確
造成很多痛苦的原因..
public function serialize()
{
return serialize(array(
$this->id, $this->username, $this->password, // see section on salt below
// $this->salt,
));
}
public function unserialize($serialized)
{
list ($this->id, $this->username, $this->password, // see section on salt below
// $this->salt
) = unserialize($serialized, array('allowed_classes' => false));
}
固定
public function serialize()
{
return serialize(array(
$this->id, $this->username, $this->password, $this->salt,
));
}
public function unserialize($serialized)
{
list ($this->id, $this->username, $this->password, $this->salt)
= unserialize($serialized, array('allowed_classes' => false));
}
用戶創建...
$user->setSalt(bin2hex(random_bytes(16)));
$encoder = new MessageDigestPasswordEncoder('sha512', true, 5000);
$encodedPassword = $encoder->encodePassword($password, $user->getSalt());
$user->setPassword($encodedPassword);
在從 Symfony2 到 Symfony 5 的項目遷移過程中遇到了這個問題。所以,我做了什么:
將用戶實體文件重命名為 User.php_
按照文檔中的描述運行 php bin/console make:user
然后將來自生成實體的方法與現有實體進行比較。
另外,從 User 實體中刪除了 \\Serializable 接口,因為我不需要它(如果您需要一個實體可序列化,只需正確實現它)
如果你從舊版本的 Symfony 遷移到 4/5 版本,最好用所有相關的東西(比如配置、登錄和注冊控制器)重新生成表單登錄並重新實現它: https : //symfony.com /doc/current/security/form_login_setup.html
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.