gpt4 book ai didi

symfony - 添加验证码到 Symfony2 登录页面

转载 作者:行者123 更新时间:2023-12-02 09:30:10 25 4
gpt4 key购买 nike

我是 Symfony2 的新手,但阅读了很多有关它的内容。首先,我使用的是 symfony 2.1.7。以及 FOSUserBundle 用于用户设置。我已经使用用户名和密码覆盖了 fos_user-login 模板。但我想添加一个用于登录的验证码。我已经看到了 GregwarCaptchaBundle,并且根据文档,应该将新字段添加到 FormType 中。我的问题来了: symfony 或 FOSUserBundle 登录表单类型在哪里,我可以添加这个新字段或覆盖它?存在 ChangePasswordFormType、ProfileFormType... 等,但不存在 LoginFOrmType。也许这是很明显的,但我没有明白这一点,欢迎任何帮助
问题已通过某种解决方案进行了编辑
看看下面帕特帮助我的评论。我创建了一个带有 _username_passwordcaptcha 字段的新表单类型。当用户名和密码的命名以下划线开头时,对于“login_check”路由和 Symfony 身份验证来说就足够了。然而 Symfony 使用监听器来进行登录过程。这是UsernamePasswordFormAuthenticationListener类。虽然我在 Form 类型中添加了验证码字段,但在登录过程中它总是被忽略。(它呈现在页面上,但该字段从未被验证,它只是被忽略。)

public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('_username', 'email', array('label' => 'form.username', 'translation_domain' => 'FOSUserBundle')) // TODO: user can login with email by inhibit the user to enter username
->add('_password', 'password', array(
'label' => 'form.current_password',
'translation_domain' => 'FOSUserBundle',
'mapped' => false,
'constraints' => new UserPassword()))
->add('captcha', 'captcha');
}

正如我上面提到的 UsernamePasswordFormAuthenticationListener 类获取表单输入值,然后重定向您:

public function __construct(SecurityContextInterface $securityContext, AuthenticationManagerInterface $authenticationManager, SessionAuthenticationStrategyInterface $sessionStrategy, HttpUtils $httpUtils, $providerKey, AuthenticationSuccessHandlerInterface $successHandler, AuthenticationFailureHandlerInterface $failureHandler, array $options = array(), LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null, CsrfProviderInterface $csrfProvider = null)
{
parent::__construct($securityContext, $authenticationManager, $sessionStrategy, $httpUtils, $providerKey, $successHandler, $failureHandler, array_merge(array(
'username_parameter' => '_username',
'password_parameter' => '_password',
'csrf_parameter' => '_csrf_token',
'captcha' => 'captcha',
'intention' => 'authenticate',
'post_only' => true,
), $options), $logger, $dispatcher);

$this->csrfProvider = $csrfProvider;
}

添加了验证码字段。

protected function attemptAuthentication(Request $request)
{
if ($this->options['post_only'] && 'post' !== strtolower($request->getMethod())) {
if (null !== $this->logger) {
$this->logger->debug(sprintf('Authentication method not supported: %s.', $request->getMethod()));
}

return null;
}

if (null !== $this->csrfProvider) {
$csrfToken = $request->get($this->options['csrf_parameter'], null, true);

if (false === $this->csrfProvider->isCsrfTokenValid($this->options['intention'], $csrfToken)) {
throw new InvalidCsrfTokenException('Invalid CSRF token.');
}
}

// check here the captcha value
$userCaptcha = $request->get($this->options['captcha'], null, true);
$dummy = $request->getSession()->get('gcb_captcha');
$sessionCaptcha = $dummy['phrase'];
// if captcha is not correct, throw exception
if ($userCaptcha !== $sessionCaptcha) {
throw new BadCredentialsException('Captcha is invalid');
}

$username = trim($request->get($this->options['username_parameter'], null, true));
$password = $request->get($this->options['password_parameter'], null, true);

$request->getSession()->set(SecurityContextInterface::LAST_USERNAME, $username);

return $this->authenticationManager->authenticate(new UsernamePasswordToken($username, $password, $this->providerKey));
}

现在,我的登录屏幕上有验证码。我知道,使用 symfony 代码并不是一个好方法。如果我找到某种方法来覆盖并调用我自己的函数,我会发布它。
另一个有用的答案

我找到了另一个可能有用的答案[链接]Is there any sort of "pre login" event or similar?

按照此解决方案,我只需覆盖 UsernamePasswordFormAuthenticationListener 类并覆盖安全监听器 security.authentication.listener.form.class 参数。代码如下:

namespace TCAT\StaffBundle\Listener;

use Symfony\Component\Security\Http\Firewall\UsernamePasswordFormAuthenticationListener as BaseListener; use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Log\LoggerInterface; use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface; use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface; use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface; use Symfony\Component\Security\Http\HttpUtils; use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; use Symfony\Component\Security\Core\Exception\InvalidCsrfTokenException; use Symfony\Component\Security\Core\SecurityContextInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\Security\Core\Exception\BadCredentialsException;


class StaffLoginFormListener extends BaseListener
{
private $csrfProvider;

/**
* {@inheritdoc}
*/
public function __construct(SecurityContextInterface $securityContext, AuthenticationManagerInterface $authenticationManager, SessionAuthenticationStrategyInterface $sessionStrategy, HttpUtils $httpUtils, $providerKey, AuthenticationSuccessHandlerInterface $successHandler, AuthenticationFailureHandlerInterface $failureHandler, array $options
= array(), LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null, CsrfProviderInterface $csrfProvider = null)
{
parent::__construct($securityContext, $authenticationManager, $sessionStrategy, $httpUtils, $providerKey, $successHandler, $failureHandler, array_merge(array(
'username_parameter' => '_username',
'password_parameter' => '_password',
'csrf_parameter' => '_csrf_token',
'captcha' => 'captcha',
'intention' => 'authenticate',
'post_only' => true,
), $options), $logger, $dispatcher);

$this->csrfProvider = $csrfProvider;
}

/**
* {@inheritdoc}
*/
protected function attemptAuthentication(Request $request)
{
if ($this->options['post_only'] && 'post' !== strtolower($request->getMethod())) {
if (null !== $this->logger) {
$this->logger->debug(sprintf('Authentication method not supported: %s.', $request->getMethod()));
}

return null;
}

if (null !== $this->csrfProvider) {
$csrfToken = $request->get($this->options['csrf_parameter'], null, true);

if (false === $this->csrfProvider->isCsrfTokenValid($this->options['intention'], $csrfToken)) {
throw new InvalidCsrfTokenException('Invalid CSRF token.');
}
}

// throw new BadCredentialsException('Bad credentials');
$userCaptcha = $request->get($this->options['captcha'], null, true);
$dummy = $request->getSession()->get('gcb_captcha');
$sessionCaptcha = $dummy['phrase'];

if ($userCaptcha !== $sessionCaptcha) {
throw new BadCredentialsException('Captcha is invalid');
}

$username = trim($request->get($this->options['username_parameter'], null, true));
$password = $request->get($this->options['password_parameter'], null, true);

$request->getSession()->set(SecurityContextInterface::LAST_USERNAME, $username);

return $this->authenticationManager->authenticate(new UsernamePasswordToken($username, $password, $this->providerKey));
}



}

并将 security.authentication.listener.form.class: TCAT\StaffBundle\Listener\StaffLoginFormListener 行添加到 app/config/paramaters.yml顺便说一句,我可以检查我的验证码值。我希望这一切对你有用。

最佳答案

Adding Captcha to Symfony2 Login Page

我不确定这是个好主意。但这是可行的。

Where is the symfony or FOSUserBundle login form type?

没有用于登录的表单类型。该表单直接嵌入到模板中,如 login.html.twig 中所示。 。

How could you do it?

您完全可以创建一个,但您必须自定义 SecurityController以便您将表单发送到模板。

<小时/>

程序是这样的:

1. 创建自定义 loginFormType(您可以在构建器中添加验证码)。

2. 覆盖 SecurityController (您可以查看 here 以查看类似的内容)。您需要重写 loginAction 方法,以便可以将表单传递到模板 here .

3. 覆盖 login.html.twig 以呈现从 Controller 传递的表单

<小时/>

编辑:回复您的评论

How can you access to your form in a controller that extends ContainerAware?

我强烈推荐this reading了解如何远离基本 Controller 。现在,你怎么能做到这一点?

那么,你有两个选择:

选项 1:简单方法

$form = $this->createForm(new LoginFormType(), null);

变成:

$form = $this->get('form.factory')->create(new LoginFormType(), $null);

选项 2:将注册表作为服务

1. 创建您的 formType(正常过程):loginFormType

2. 将表单定义为服务 acme_user.login.form。你有一个很好的例子here (在 1.2 版本的 FOSUserBundle 中,注册表单和个人资料表单都注册为服务,因此这为您提供了一个完美的示例来说明它是如何完成的)。

3. 现在,您可以在扩展 ContainerAware 的 Controller 中使用表单。请参阅here .

$form = $this->container->get('acme_user.login.form');

关于symfony - 添加验证码到 Symfony2 登录页面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14788828/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com