从Symfony 4升级到最新的Symfony 5版本后,我尝试升级我的注册和登录表单保护功能,使其成为验证器功能。
在尝试了很多东西,并一次又一次地使用make: user
和make: auth
命令后,我现在处于一个没有警告,没有错误的情况下,只是当我试图登录时,什么都没有发生:没关系无论用户名/密码组合是否正确,我只是回到登录表单。
以下是我认为可能与该问题相关的文件:
配置/包/security.yaml
security:
enable_authenticator_manager: true
password_hashers:
App\Entity\Player:
algorithm: auto
providers:
app_user_provider:
entity:
class: App\Entity\Player
property: email
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
lazy: true
provider: app_user_provider
custom_authenticator: App\Security\LoginFormAuthenticator
logout:
path: app_logout
remember_me:
secret: '%kernel.secret%'
lifetime: 604800
path: /
always_remember_me: true
switch_user: true
access_control:
# - { path: ^/admin, roles: ROLE_ADMIN }
# - { path: ^/profile, roles: ROLE_USER }
src/Controller/SecurityController.php
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
class SecurityController extends AbstractController
{
/**
* @Route("/login", name="app_login")
*/
public function login(AuthenticationUtils $authenticationUtils): Response
{
// If the user is logged in, redirect them to their profile page.
if ($this->getUser()) {
return $this->redirectToRoute('player_control_panel');
}
// get the login error if there is one
$error = $authenticationUtils->getLastAuthenticationError();
// last username entered by the user
$lastUsername = $authenticationUtils->getLastUsername();
return $this->render('security/login.html.twig', ['last_username' => $lastUsername, 'error' => $error]);
}
/**
* @Route("/logout", name="app_logout")
*/
public function logout()
{
throw new \LogicException('This method can be blank - it will be intercepted by the logout key on your firewall.');
}
}
src/Entity/Player.php
<?php
namespace App\Entity;
use App\Repository\PlayerRepository;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* @ORM\Entity(repositoryClass=PlayerRepository::class)
* @UniqueEntity(fields={"email"}, message="There is already an account with this email")
*/
class Player implements UserInterface, PasswordAuthenticatedUserInterface
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=180, unique=true)
*/
private $email;
/**
* @ORM\Column(type="json")
*/
private $roles = [];
/**
* @var string The hashed password
* @ORM\Column(type="string")
*/
private $password;
/**
* @ORM\Column(type="boolean")
*/
private $isVerified = false;
public function getId(): ?int
{
return $this->id;
}
public function getEmail(): ?string
{
return $this->email;
}
public function setEmail(string $email): self
{
$this->email = $email;
return $this;
}
/**
* A visual identifier that represents this user.
*
* @see UserInterface
*/
public function getUserIdentifier(): string
{
return (string) $this->email;
}
/**
* @deprecated since Symfony 5.3, use getUserIdentifier instead
*/
public function getUsername(): string
{
return (string) $this->email;
}
/**
* @see UserInterface
*/
public function getRoles(): array
{
$roles = $this->roles;
// guarantee every user at least has ROLE_USER
$roles[] = 'ROLE_USER';
return array_unique($roles);
}
public function setRoles(array $roles): self
{
$this->roles = $roles;
return $this;
}
/**
* @see PasswordAuthenticatedUserInterface
*/
public function getPassword(): string
{
return $this->password;
}
public function setPassword(string $password): self
{
$this->password = $password;
return $this;
}
/**
* Returning a salt is only needed, if you are not using a modern
* hashing algorithm (e.g. bcrypt or sodium) in your security.yaml.
*
* @see UserInterface
*/
public function getSalt(): ?string
{
return null;
}
/**
* @see UserInterface
*/
public function eraseCredentials()
{
// If you store any temporary, sensitive data on the user, clear it here
// $this->plainPassword = null;
}
public function isVerified(): bool
{
return $this->isVerified;
}
public function setIsVerified(bool $isVerified): self
{
$this->isVerified = $isVerified;
return $this;
}
}
src/Security/LoginFormAuthenticator.php
<?php
namespace App\Security;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Http\Authenticator\AbstractLoginFormAuthenticator;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\CsrfTokenBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials;
use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface;
use Symfony\Component\Security\Http\Util\TargetPathTrait;
class LoginFormAuthenticator extends AbstractLoginFormAuthenticator
{
use TargetPathTrait;
public const LOGIN_ROUTE = 'app_login';
private UrlGeneratorInterface $urlGenerator;
public function __construct(UrlGeneratorInterface $urlGenerator)
{
$this->urlGenerator = $urlGenerator;
}
public function authenticate(Request $request): PassportInterface
{
$email = $request->request->get('email', '');
$request->getSession()->set(Security::LAST_USERNAME, $email);
return new Passport(
new UserBadge($email),
new PasswordCredentials($request->request->get('password', '')),
[
new CsrfTokenBadge('authenticate', $request->request->get('_csrf_token')),
]
);
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
{
$request->getSession()->getFlashBag()->add('success', "You are now signed in. Greetings, commander.");
if ($targetPath = $this->getTargetPath($request->getSession(), $firewallName)) {
return new RedirectResponse($targetPath);
}
return new RedirectResponse($this->urlGenerator->generate('app_index'));
}
protected function getLoginUrl(Request $request): string
{
return $this->urlGenerator->generate(self::LOGIN_ROUTE);
}
}
我只是看不出哪里出了问题,如果你有一个想法,或者即使你能给我一个想法,让我知道哪里出了问题,我会很感激的。非常感谢。
抱歉,这是一个重复的Symfony simple登录表单,新的身份验证方法不起作用,我在发布后几分钟发现了它(我发誓我以前搜索过,但没有找到它)。
问题确实是authenticator类中缺少supports()
方法,抽象登录表单authenticator中的方法显然是不够的。添加该方法修复了它:
在src/Security/LoginFormAuthenticator.php
public function supports(Request $request): bool
{
return self::LOGIN_ROUTE === $request->attributes->get('_route')
&& $request->isMethod('POST');
}
完整文件:
<?php
namespace App\Security;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Http\Authenticator\AbstractLoginFormAuthenticator;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\CsrfTokenBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials;
use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface;
use Symfony\Component\Security\Http\Util\TargetPathTrait;
class LoginFormAuthenticator extends AbstractLoginFormAuthenticator
{
use TargetPathTrait;
public const LOGIN_ROUTE = 'app_login';
private UrlGeneratorInterface $urlGenerator;
public function __construct(UrlGeneratorInterface $urlGenerator)
{
$this->urlGenerator = $urlGenerator;
}
public function supports(Request $request): bool
{
return self::LOGIN_ROUTE === $request->attributes->get('_route')
&& $request->isMethod('POST');
}
public function authenticate(Request $request): PassportInterface
{
$email = $request->request->get('email', '');
$request->getSession()->set(Security::LAST_USERNAME, $email);
return new Passport(
new UserBadge($email),
new PasswordCredentials($request->request->get('password', '')),
[
new CsrfTokenBadge('authenticate', $request->request->get('_csrf_token')),
]
);
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
{
$request->getSession()->getFlashBag()->add('success', "You are now signed in. Greetings, commander.");
if ($targetPath = $this->getTargetPath($request->getSession(), $firewallName)) {
return new RedirectResponse($targetPath);
}
return new RedirectResponse($this->urlGenerator->generate('app_index'));
}
protected function getLoginUrl(Request $request): string
{
return $this->urlGenerator->generate(self::LOGIN_ROUTE);
}
}
1.1.1. 系统升级 1.1.1. 系统升级 根据系统升级介绍,应用层接口只需写入 misc 分区标志位接口。 接口 上层应用程序由 Nodejs 调用,底层提供了 librecovery C库,此库提供了写升级标志的接口,第三方厂商可以根据此进行修改自己的 OTA 升级。 struct boot_cmd { char boot_mode[32]; // 升级
1.1. 系统升级 1.1.1. 系统分区 1.1.2. 升级流程 1.1. 系统升级 RokidOS 为第三方厂商提供了 OTA 相关方案。 1.1.1. 系统分区 由于文件系统的问题,线刷的固件包为aml_upgrade_package.img,而 OTA 所使用的固件包为rokid_upgrade_package.img,二者打包格式不同在于 system 分区的不同。 对于采用 Amlog
1.1. 目录 1.1.1. 系统发布服务 1.1.2. 系统发布流程 1.1.3. 分组管理 1.1. 目录 本文介绍如何通过“Rokid开放平台”对设备进行系统升级。 一、系统发布服务 二、系统发布流程 三、分组管理 1.1.1. 系统发布服务 可通过此服务既可以进行全量升级,也可以进行分组升级,还可以区分测试版本、灰度版本和正式版本。在文件选择时支持两种方式:1)自有服务器填写升级文件路径;
我们没有通过magento连接安装m2epro,因此我们无法升级M2epro。M2epro支持团队建议删除以下文件并使用Magento连接安装。 应用程序/代码/社区/Ess/M2ePro、应用程序/设计/adminhtml/默认/默认/布局/M2ePro.xml、应用程序/设计/adminhtml/默认/默认/模板/M2ePro、应用程序/等/模块/Ess_M2ePro.xml、js/M2ePr
我目前正在使用登录系统将GCM实现到一个应用程序中。我想根据登录到应用程序的用户(一个设备,多个用户)向应用程序发送通知。我经历了这些过程。 以“用户A”身份登录 我不确定如何让应用程序识别登录到设备的用户,并将消息推送给该特定用户。而不是用户B登录并获得用户A的通知。任何意见和答案将高度赞赏!如果您需要检查我的项目的特定代码,请让我知道。
我使用的是Spring Security 4.1.1,但我遇到了一个问题:我试图访问URL,应用程序会重定向到登录页面。到现在为止,一直都还不错。 但是,成功登录后,应用程序会再次将我重定向到登录页面,并且不会创建任何会话,因此即使尝试直接访问URL(在URL栏中键入),应用程序也会重定向到登录页面。 有一些URL我必须要求登录才能访问它们。其他的,我可以访问无需身份验证。这些我不需要验证的URL