Symfony simple login - symfony

i to do login in my webpage about symfony documentation example and i have a little problem. It's work but work a second time, after i clear cache. In first time i catch error with your session time out or you disabled cookie.
it's base.html.twig
{% if is_granted('ROLE_USER') %}
<div class="content">
<div class="starter-template">
{% block body %}{% endblock %}
</div>
</div>
{% else %}
<div class="container">
<div class="row">
<div class="col-md-offset-5 col-md-3">
<div class="form-login">
<h4>Welcome back.</h4>
<form action="{{ path('login') }}" method="post">
<input type="text" name="_username" id="userName" class="form-control input-sm chat-input" placeholder="username" />
</br>
<input type="password" name="_password" id="userPassword" class="form-control input-sm chat-input" placeholder="password" />
</br>
<div class="wrapper">
<span class="group-btn">
<button type="submit" href="#" class="btn btn-primary btn-md">login <i class="fa fa-sign-in"></i></button>
</span>
</div>
</form>
</div>
</div>
</div>
</div>
{% endif %}
and login action:
/**
* #Route("/login", name="login")
*/
public function loginAction(Request $request)
{
$authenticationUtils = $this->get('security.authentication_utils');
$error = $authenticationUtils->getLastAuthenticationError();
$lastUsername = $authenticationUtils->getLastUsername();
return $this->render('security/login.html.twig', array(
'last_username' => $lastUsername,
'error' => $error,
));
}
I try return redirect in this action but nothing helps me.
If login to do in /login page it's work okey. But I want use with which construction how in base.html

Try work on dev mode.
1) Go on web directory
2) Open app.php file
3) Change the code inside app.php to
$kernel = new AppKernel('dev', true);
$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);
Remove from controller
/**
* #Route("/login", name="login")
*/
Finally try move route in routing file.
For example in routing.yml:
login:
path: /login
defaults: { _controller: YourNameBundle:NameYourController:login }

Related

login root path / on symfony instead /login

<!-- templates/bootstrap/login/form-login.html.twig-->
<div class="container">
<div class="row">
<div style="padding-right: 0px;" class="col-12">
<form method="post">
<label for="inputEmail">Email</label>
<input type="email" value="{{ last_username }}" name="email" id="inputEmail" class="form-control" autocomplete="email" required autofocus>
<label for="inputPassword">Password</label>
<input type="password" name="password" id="inputPassword" class="form-control" autocomplete="current-password" required>
<input type="hidden" name="_csrf_token"
value="{{ csrf_token('authenticate') }}"
>
{% if error %}
<div class="alert alert-danger">{{ error.messageKey|trans(error.messageData, 'security') }}</div>
{% endif %}
{% if app.user %}
<div style="margin-top: 10px;" class="mb-3">
You are logged in as {{ app.user.username }}, Logout
</div>
{% endif %}
<button style="margin-top: 10px; width: 100%;" class="btn btn-primary" type="submit">
Sign in
</button>
</form>
<div style="border-top: 1px solid black; height: 1px;margin-top: 10px;"></div>
<a style="width: 100%;" href="/registration" class="btn btn-outline-primary">Create an account</a>
<div style="height: 1px;margin-bottom: 10px;"></div>
</div>
</div>
</div>
All work correctly on "http://webserver5.com:8001/login" path.
But It doesn't work on "http://webserver5.com:8001/" path.
If I enter email and password correctly or incorrectly I obtain only refresh page. Why?
I want "/" root path because to point a login method controller.
Can you help me please.
<?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_welcome';
private $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->get('_csrf_token')),
]
);
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
{
if ($targetPath = $this->getTargetPath($request->getSession(), $firewallName)) {
return new RedirectResponse($targetPath);
}
// For example:
return new RedirectResponse($this->urlGenerator->generate('app_contact_index'));
//throw new \Exception('TODO: provide a valid redirect inside '.__FILE__);
}
protected function getLoginUrl(Request $request): string
{
return $this->urlGenerator->generate(self::LOGIN_ROUTE);
}
}
public const LOGIN_ROUTE = 'app_welcome';
This route app_welcome is defined thus:
/
App\Controller\SecurityController::login
Now it works.

Unable to render the form because the block names array contains duplicates

i'm using Symfony 3.3.9 and when I'm trying to render a form I have the following error:
An exception has been thrown during the rendering of a template
("Unable to render the form because the block names array contains
duplicates: "_fos_user_registration_form_errors", "user_errors",
"user_errors", "fos_user_registration_errors", "form_errors".").
Thank you in advance for your help !
EDIT 17/09/2017
Here you go:
public function indexAction()
{
/** #var $formFactory FactoryInterface */
$formFactory = $this->get('fos_user.registration.form.factory');
$form = $formFactory->createForm();
return $this->render('AppTMMainBundle:Default:index.html.twig', array(
'form' => $form->createView(),
));
}
My Twig:
{{ form_start(form, {'method': 'post', 'action': path('fos_user_registration_register')}) }}
<div class="card-content">
<h3 class="text-center title" style="color: #3C4858;margin:10px 0;">Inscription</h3>
<div class="social text-center">
<a class="btn btn-just-icon btn-round btn-facebook" href="{{ path('hwi_oauth_service_redirect',{'service': 'facebook'}) }}">
<i class="fa fa-facebook"> </i>
</a>
<a class="btn btn-just-icon btn-round btn-twitter" href="{{ path('hwi_oauth_service_redirect',{'service': 'twitter'}) }}">
<i class="fa fa-twitter"></i>
</a>
<a class="btn btn-just-icon btn-round btn-google" href="{{ path('hwi_oauth_service_redirect',{'service': 'google'}) }}">
<i class="fa fa-google-plus"></i>
</a>
</div>
<p class="description text-center">Ou de façon plus classique</p>
<div class="row">
<div class="col-xs-6">
{{ form_label(form.firstname) }}
{{ form_widget(form.firstname) }}
</div>
<div class="col-xs-6">
{{ form_label(form.lastname) }}
{{ form_widget(form.lastname) }}
</div>
</div>
<div class="row">
<div class="col-xs-12">
{{ form_label(form.email) }}
{{ form_widget(form.email) }}
</div>
</div>
<div class="row">
<div class="col-xs-6">
{{ form_widget(form.plainPassword.first, {'attr': {'class': 'form-control', 'placeholder': 'form.password'}}) }}
</div>
<div class="col-xs-6">
{{ form_widget(form.plainPassword.second, {'attr': {'class': 'form-control', 'placeholder': 'form.password_confirmation'}}) }}
</div>
</div>
<!-- If you want to add a checkbox to this form, uncomment this code -->
<div class="input-group">
<div class="checkbox">
<label>
<input type="checkbox" name="optionsCheckboxes" checked="">
{{ 'index.proceed.agree'|trans }} {{ 'index.proceed.cgu'|trans }}.
</label>
</div>
</div>
<div class="footer text-center">
<input type="submit" class="btn btn-primary btn-round" value="{{ 'index.action.subscribe'|trans }}">
</div>
</div>
{{ form_end(form) }}
for anyone having such an exception:
You probably shouldn't extend a form type, but instead create your own and use getParent to inherit the behaviour.
And if your class name is the same as an other type (excluding namespaces)
you must override the getBlockPrefix from AbstractType.
The getBlockPrefix method from AbstractType uses the last part of fqcn (the class name) and you could have a duplicate block name.
I found the answer to my question.
That was from my RegistrationType class where I was trying to extends with another Type Class. getParent not working as well expected...
RegistrationType > UserType > FOS\UserBundle\Form\Type\RegistrationFormType
I move all fields from UserType in RegistrationType and it's working :)

Symfony2 getLastUsername() function not working

I'm creating my first Symfony2 login form and want to use the getLastUsername() function to set the value of the username textbox but when calling the function it simply returns an empty string.
This is my SecurityController.php file:
<?php
namespace AppBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
class SecurityController extends Controller
{
/**
* #Route("/login", name="login")
*/
public function loginAction(Request $request)
{
$authenticationUtils = $this->get('security.authentication_utils');
// 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',
array(
// last username entered by the user
'last_username' => $lastUsername,
'error' => $error,
)
);
}
/**
* #Route("/login_check", name="login_check")
*/
public function loginCheckAction()
{
}
}
?>
and my Twig template for the form:
{# app/Resources/views/security/login.html.twig #}
{% extends 'base.html.twig' %}
{% block stylesheets %}
{{ parent() }}
<link href="{{ asset('css/login.css') }}" rel="stylesheet" />
{% endblock %}
{% block javascripts %}
{{ parent() }}
<script src="{{ asset('js/login.js') }}"></script>
{% endblock %}
{% block body %}
<div id="container">
{% if error %}
<div class="alert alert-danger">{{ error.messageKey|trans(error.messageData, 'security') }}</div>
{% endif %}
<div id="loginbox">
<form id="loginform" action="{{ path('login_check') }}" method="post">
<p>Enter username and password to continue.</p>
<div class="input-group input-sm">
<span class="input-group-addon"><i class="fa fa-user"></i></span><input class="form-control" type="text" name="_username" id="username" placeholder="Username" value="{{ last_username }}" />
</div>
<div class="input-group">
<span class="input-group-addon"><i class="fa fa-lock"></i></span><input class="form-control" type="password" name="_password" id="password" placeholder="Password" />
</div>
<div class="form-actions clearfix">
<div class="pull-left">
Create new account
</div>
<div class="pull-right">
Lost password?
</div>
<input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}" />
<input type="submit" class="btn btn-block btn-primary btn-default" value="Login" />
</div>
</form>
</div>
</div>
{% endblock %}
Everything works fine. Logged in and out many times but the las username isn't showing. Thought Symfony might be using cookies to save the last used username but it isn't creating any cookies, only the PHP session is saved in a cookie. Is it a problem in the cookie configurations or may be something else?
Thanks,

Symfony2 - Wrong controller action called

I am doing a lot on the page and I think I am getting a conflict somewhere. Basically, my page initially shows an input and a blank div. When an input is provided and submitted, the page refreshed with the div full of data. The user can then select some of this data and finally submit again.
This is my view
{% block main %}
<div class="col-md-4">
<section class="panel panel-default">
<header class="panel-heading">
<h3 class="panel-title">Terminal</h3>
</header>
<div class="panel-body">
<form action="{{ path('NickAlertBundle_terminalSearch') }}" method="post" enctype="multipart/form-data" class="terminalForm" id="terminalForm">
<div class="row">
<div class="col-md-12">
<input type="text" class="addMargin" id="terminal_command" name="terminal_command" placeholder=">">
</div>
</div>
<div class="row">
<div class="col-md-8 col-md-offset-4">
<input type="submit" class="btn btn-default" id="terminal_submit" value="Submit">
</div>
</div>
</form>
</div>
</section>
</div>
<div class="col-md-8" id="terminal-window">
<table class="terminalAvailability">
{% if data is defined %}
<form action="{{ path('NickAlertBundle_terminalCreate') }}" method="post" enctype="multipart/form-data" class="terminalForm">
{% for info in data %}
<tr>
<td class="flightNumber">{{ info.flightNumber }}</td>
<td class="details">{{ info.from ~ info.to }}</td>
{% for seat, availability in info.seats %}
<td class="seatClass">
<label for="{{ seat }}">
<span>{{ seat ~ availability }}</span>
</label>
<input type="checkbox" id="{{ seat }}" name="seats[{{ info.flightNumber }}][]" style="display: none;" value="{{ seat }}" />
</td>
{% endfor %}
<td class="otherInfo">{{ info.other }}</td>
</tr>
{% endfor %}
<div class="row">
<div class="col-md-8 col-md-offset-4">
<input type="submit" class="btn btn-default" value="Submit">
</div>
</div>
</form>
{% endif %}
</table>
</div>
<div class="modal"></div>
{% endblock %}
The first div is the input and the second div is the div the data will be displayed, selected, and resubmitted.
I then have my controller actions
public function terminalAction()
{
return $this->render('NickAlertBundle:Page:terminal.html.twig');
}
public function terminalSearchAction(Request $request)
{
try {
$terminal_command = strtoupper($request->get('terminal_command'));
$error = array();
if (!$terminal_command) {
$error[] = "Please enter the Command";
}
if (count($error)) {
echo "There were errors adding the alert.\n\n";
foreach ($error as $item) {
echo $item . "\n";
}
die();
}
$uapiService = $this->container->get('alert_bundle.api_service');
$commandData = $apiService->terminalService($terminal_command);
return $this->render('NickAlertBundle:Page:terminal.html.twig', array(
'data' => $commandData,
));
}catch (Exception $e) {
}
}
public function terminalCreateAction(Request $request)
{
try {
foreach ($request->request->get('seats') as $row) {
foreach ($row as $seat) {
var_dump($seat);
}
}
return $this->render('NickAlertBundle:Page:terminal.html.twig');
}catch (Exception $e) {
}
}
And finally my routes
NickAlertBundle_terminal:
pattern: /terminal
defaults: { _controller: NickAlertBundle:Alert:terminal }
methods: [GET]
NickAlertBundle_terminalSearch:
pattern: /terminal
defaults: { _controller: NickAlertBundle:Alert:terminalSearch }
methods: [POST]
NickAlertBundle_terminalCreate:
pattern: /terminal
defaults: { _controller: NickAlertBundle:Alert:terminalCreate }
methods: [POST]
So the page is initially displayed fine. The user then enters some input, submits it, and the response data is then displayed in the div. So this means the first two routes work perfectly. With the data in the div, the user can select some data, and then submit it. However, when this data is submitted, they are displayed with
There were errors adding the alert. Please enter the Command
This error is for the second action, and should not have anything to do with the third action. The second form has its path set to NickAlertBundle_terminalCreate so why would it cross wires with the other action?
Thanks
NickAlertBundle_terminalCreate will always solve to NickAlertBundle_terminalSearch, because the RouteMatcher will always match the pattern /terminal + method POST to the first route with these rules.
Why not give NickAlertBundle_terminalSearch a pattern like /terminal/search?

Creating a Horizontal form with Braincrafted Bootstrap

I'm trying to create a Twitter Bootstrap based horizontal form using Symfony and the Braincrafted Bootstrap module. I've copied the example from the docs however my form is not rendering correctly
My code is as follows
class MyController extends Controller {
/**
* #Route("/")
* #Method("GET")
* #Template
*/
public function someAction() {
$form = $this->createForm(new HorizontalFormType());
return array("horizontalForm" => $form->createView());
}
}
This class is taken from the docs:
class HorizontalFormType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder->add('email', 'text', array(
'label' => 'Email',
'attr' => array('placeholder' => 'Email')
));
$builder->add('password', 'password', array(
'label' => 'Password',
'attr' => array('placeholder' => 'Password')
));
$builder->add('checkbox', 'checkbox', array('label' => 'Remember me'));
}
public function getName() {
return 'horizontal_form';
}
}
The template code is copied as well
<form class="form-horizontal">
<legend>Legend</legend>
{{ form_widget(horizontalForm, {'form_type': 'horizontal'}) }}
<div class="control-group">
<div class="controls">
<button type="submit" class="btn">Sign in</button>
</div>
</div>
</form>
The resulting HTML for the form is
<form class="form-horizontal ng-pristine ng-valid">
<legend>Legend</legend>
<div id="horizontal_form">
<div>
<label class="required" for="horizontal_form_email">Email</label>
<input type="text" placeholder="Email" required="required" name="horizontal_form[email]" id="horizontal_form_email">
</div>
<div>
<label class="required" for="horizontal_form_password">Password</label>
<input type="password" placeholder="Password" required="required" name="horizontal_form[password]" id="horizontal_form_password">
</div>
<div>
<label class="required" for="horizontal_form_checkbox">Remember me</label><input type="checkbox" value="1" required="required" name="horizontal_form[checkbox]" id="horizontal_form_checkbox">
</div>
<input type="hidden" value="fea7c498a01aebd814baf4a9f57df4b6e3646195" name="horizontal_form[_token]" id="horizontal_form__token">
</div>
<div class="control-group">
<div class="controls">
<button class="btn" type="submit">Sign in</button>
</div>
</div>
</form>
Note I'm also using AngularJS in my project (hence why the ng directives are added to the form's class list).
What have I missed?
As described in the Getting Started guide in the "Form Theme" section, I had to manually configure Symfony to use the Braincrafted form template. It did not unfortunately automatically work.
twig:
form:
resources:
- "BraincraftedBootstrapBundle:Form:form_div_layout.html.twig"
For braincrafted-bootstrap up to v1.4, to make any form horizontal from within a twig,
{{ form(form, {'form_type': 'horizontal', 'attr': {'class': 'form-horizontal'}}) }}
"form-type" tells BC_Bootstrap to add the control groups for you, and the attr: class: then tells bootstrap css to apply the horizontal style. You need to have both of these applied.
This means that you don't need to extend any horizontal formTypes, nor break the form out into widgets et al in order to set the class. Just apply the form_type and class in the twig as above.
You must Wrap labels and controls in .control-group
All labels must have class .control-label.Input fields must be wrapped with div class="controls". The html output should be like this
<form class="bs-docs-example form-horizontal">
<legend>Legend</legend>
<div id="horizontal_form">
<div class="control-group">
<label for="horizontal_form_email" class="required control-label">Email</label>
<div class="controls">
<input type="text" id="horizontal_form_email" name="horizontal_form[email]" required="required" placeholder="Email">
</div>
</div>
<div class="control-group">
<label for="horizontal_form_password" class="required control-label">Password</label>
<div class="controls">
<input type="password" id="horizontal_form_password" name="horizontal_form[password]" required="required" placeholder="Password">
</div>
</div>
<div class="control-group">
<div class="controls">
<label for="horizontal_form_checkbox" class="checkbox required">
<input type="checkbox" id="horizontal_form_checkbox" name="horizontal_form[checkbox]" required="required" value="1"> Remember me
</label>
</div>
</div>
<input type="hidden" id="horizontal_form__token" name="horizontal_form[_token]" value="def76ca43f623d0a4ad8145e39f33907b7e9e0a1"></div>
<div class="control-group">
<div class="controls">
<button type="submit" class="btn">Sign in</button>
</div>
</div>
</form>

Resources