How to override layout.html.twig from FOSUserBundle - php

I know that this question is perfectly answered in FOSUserBundle documentation, but yet I can't solve my problem.
I am trying to make an own login page using FOSUserBundle.
I have a main.html.twig that is EXACTLY the same as the login.html.twig included in the FOSUserBundle source.
The only difference is that main.html.twig is in my own bundle structure and login.html.twig is in FOSUserBundle folder structure.
I reach both /login and /main. I resolve them and the render starts.
But when accessing /main, I get the following error:
Twig_Error_Runtime: Variable "csrf_token" does not exist in "AcmeStoreBundle:Main:main.html.twig" at line 5
The code is known by the FOSUserBundle users, but anyway I paste it here:
<form action="{{ path("fos_user_security_check") }}" method="post">
<input type="hidden" name="_csrf_token" value="{{ csrf_token }}" />
<label for="username">{{ 'security.login.username'|trans({}, 'FOSUserBundle') }}</label>
<input type="text" id="username" name="_username" value="" />
<label for="password">{{ 'security.login.password'|trans({}, 'FOSUserBundle') }}</label>
<input type="password" id="password" name="_password" />
<input type="checkbox" id="remember_me" name="_remember_me" value="on" />
<label for="remember_me">{{ 'security.login.remember_me'|trans({}, 'FOSUserBundle') }}</label>
<input type="submit" id="_submit" name="_submit" value="{{ 'security.login.submit'|trans({}, 'FOSUserBundle') }}" />
The variable "csrf_token" is somehow not recognized from outside FOSUserBundle. Or something else that I am not getting.
Any clue over there?

Since you are not using FormBuilder, in your action that is responsible for rendering main.html.twig you should generate this token and pass it to the View.
$csrf = $this->get('form.csrf_provider'); //Symfony\Component\Form\Extension\Csrf\CsrfProvider\SessionCsrfProvider by default
$token = $csrf->generateCsrfToken($intention); //Intention should be empty string, if you did not define it in parameters
You should pass $token as csrf_token variable to your View
Check also my answer to similar question

Related

Unable to get auth email as field value in view (larave5.3)

I am working on laravel 5.3 and i want to get authenticated user email as my field value my field code is
<div class="col-md-8">
<input type="text" class="form-control" name="email" value="{{ isset($student->email) ? $student->email : '{{Auth::user()->email}}' }}" required />
</div>
Here above i tried as {{Auth::user()->id}}' }} but its give syntax error if
syntax error, unexpected '}'
If i try with single bracket it prints as it is
You have syntax error,
<input type="text" class="form-control" name="email" value="{{ isset($student->email) ? $student->email : Auth::user()->email }}" required />
Copy paste this code,
you tried to give {{}} inside {{}} to fetch auth details.
Give it a try, it should work.
instead of
<input type="text" class="form-control" name="email" value="{{ isset($student->email) ? $student->email : Auth::user()->email }}" required />
Try,
#php($email=Auth::user()->email)
#if(isset($student->email))
$email=$student->email
#endif
<input type="text" class="form-control" name="email" value="{{ $email }}" required />

Laravel 5 input old is empty

My routes is here
Route::get('sign-up', ['as' => 'signUp', 'uses' => 'UserController#signUpGet']);
Route::post('sign-up', ['as' => 'signUpPost', 'uses' => 'UserController#signUpPost']);
Controller
return redirect('signUp')->withInput();
And View
<form role="form" method="POST" action="{{route('signUpPost')}}">
<input type="text" class="form-control" name="username" value="{{ old('username') }}">
</form>
The {{old()}} function return empty value.
EDIT
I took
NotFoundHttpException in RouteCollection.php line 145:
Your problem looks like you are not actually submitting the username in the first place:
<form role="form" method="POST" action="{{route('signUpPost')}}">
<input type="text" class="form-control" name="username" value="{{ old('username') }}">
</form>
There is no 'submit' button inside the form. If you submit outside the form - then the username will not be included.
Add the submit button inside your form - then try again
<form role="form" method="POST" action="{{route('signUpPost')}}">
<input type="text" class="form-control" name="username" value="{{ old('username') }}">
<input type="submit" value="Submit">
</form>
Edit - also your controller is wrong. It should be this:
return redirect()->route('signUp')->withInput();
All you are missing is to Flash the Input to the session. This is so it's available during the next request.
$request->flash();
Do that just before calling to View your form.
Source: http://laravel.com/docs/5.1/requests#old-input
<div class="form-group #if($errors->first('username')) has-error #endif">
<label for="username" class="rtl">Enter user name </label>
<input type="text" name="username" class="form-control rtl basic-usage" id="username" placeholder="Enter user name" value="{!! old('username') !!}">
<span class="help-block required">{{$errors->first('username')}}</span>
</div>
above form field will show old value entered.
will show validation error (you have to specify error separately.)
have a place holder.
bootstrap to look better.(add bootstrap)
Your name in the register view should correspond with keys in create() and validate() method inside your RegisterController file.
My problem here was caused by "data-prefill" in the input. Once I removed this, it worked.
You can try this: {{ Input::old('username') }}.

FOSUserBundle (login / register) + AJAX + Symfony2

I installed FOSUserBundle on my Symfony2 website and I overwrited the login and register pages. It's working very well, but now, I have another issue :
Making a pop up with an AJAX check for the login and register part, working with the different routes, controllers, etc.
How to do that the best way ?
My pop up is a simple bootstrap modal of login.html.twig page for FOSUserBundle, here is the code of the modal-body for the login part (I will use the register form for the register part) :
<div class="modal-body">
{% trans_default_domain 'FOSUserBundle' %}
{% block fos_user_content %}
<form action="{{ path("fos_user_security_check") }}" method="post">
<input type="hidden" name="_csrf_token" value="{{ csrf_token }}" />
<label for="username">{{ 'security.login.username'|trans }}</label>
<input type="text" id="username" name="_username" value="" required="required" />
<label for="password">{{ 'security.login.password'|trans }}</label>
<input type="password" id="password" name="_password" required="required" />
<br /><br />
<input type="submit" id="_submit" name="_submit" value="{{ 'security.login.submit'|trans }}" />
</form>
{% endblock fos_user_content %}
</div>
I already searched on StackOverflow and other websites but didn't find the good answer I was looking for.
Thank you.
no token when you use AJAX
user=$('#username').val();
pass=$('password').val();
$.ajax(
{
type: "POST",
url: "{{ path ('your-rout')}}",
data: {'user': user,'pass':pass},
beforeSend: function() {
},
success: function(json) {}
});

Theme paradigm in Symfony2 [duplicate]

I've installed Symfony2, FOS User Bundle and Twitter Bootstrap.
Then I setup the /app/Resources/FOSUserBundle/views/layout.html.twig template to override FOSUserBundle to use my site template.
It all works if I have a link to /login on the homepage.
Now I want to implement a template like the hero template where the login form is part of the main template.
The closest I've got is to use this in the main template:
{% render controller("FOSUserBundle:Security:login") %}
I can override the layout html to not extend main template, but this removes all styling from /login
Any ideas how I can handle both scenarios?
You were almost there :)
you can include the login form in any other template using the render function.
{% render controller("FOSUserBundle:Security:login") %}
... you just have to create app/Resources/FOSUserBundle/views/Security/login.html.twig and ommit the wrapping {% block fos_user_content %} found in FOSUserBundle's login.html.twig in order to have it return the form directly:
{% if error %}
<div>{{ error|trans }}</div>
{% endif %}
<form action="{{ path("fos_user_security_check") }}" method="post">
<input type="hidden" name="_csrf_token" value="{{ csrf_token }}" />
<label for="username">{{ 'security.login.username'|trans }}</label>
<input type="text" id="username" name="_username" value="{{ last_username }}" required="required" />
<label for="password">{{ 'security.login.password'|trans }}</label>
<input type="password" id="password" name="_password" required="required" />
<input type="checkbox" id="remember_me" name="_remember_me" value="on" />
<label for="remember_me">{{ 'security.login.remember_me'|trans }}</label>
<input type="submit" id="_submit" name="_submit" value="{{ 'security.login.submit'|trans }}" />
</form>
Then adjust it to fit your template.
Richard Miller's post has helped me achieve what I was trying to do.
http://richardmiller.co.uk/2013/02/18/symfony2-ajax-and-full-page-templates/
{% extends app.request.attributes.get('partial')
? '::ajax-layout.html.twig'
: '::full-layout.html.twig' %}
I couldn't get app.request.partial to work, and decided choosing based on xmlRequest wasn't ideal.

Symfony2, login form - CSRF protection

I have this login form via Symfony2 security documentation with the following TWIG template content:
<form action="{{ path('login_check') }}" method="post">
<div class="input form">
<label for="username">Account name or E-mail:</label>
<input type="text" id="username" name="_username" value="{{ last_username }}" required="required" />
</div>
<div class="input form">
<label for="password">Password:</label>
<input type="password" id="password" name="_password" required="required" />
</div>
<input type="hidden" name="_token" value="{{ csrf_token("intention") }}">
<button type="submit">Log In</button>
</form>
And I want to add CSRF protection in this form. As you can see, I added this line <input type="hidden" name="_token" value="{{ csrf_token("intention") }}"> but I'm not really sure, if it is enough to activate this protection.
My controller has same form as on the doc, so it looks like this:
<?php
// src/Acme/SecurityBundle/Controller/SecurityController.php;
namespace Acme\SecurityBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Security\Core\SecurityContext;
class SecurityController extends Controller
{
public function loginAction()
{
$request = $this->getRequest();
$session = $request->getSession();
// get the login error if there is one
if ($request->attributes->has(SecurityContext::AUTHENTICATION_ERROR)) {
$error = $request->attributes->get(
SecurityContext::AUTHENTICATION_ERROR
);
} else {
$error = $session->get(SecurityContext::AUTHENTICATION_ERROR);
$session->remove(SecurityContext::AUTHENTICATION_ERROR);
}
return $this->render(
'AcmeSecurityBundle:Security:login.html.twig',
array(
// last username entered by the user
'last_username' => $session->get(SecurityContext::LAST_USERNAME),
'error' => $error,
)
);
}
}
So it's enough just paste one hidden input with value {{ csrf_token("intention") }} or I have to add something into controller?
I found that Answer from #Chris McKinnel isn't true. Now, the Symfony2 has on the tutorial page this section:
http://symfony.com/doc/current/cookbook/security/csrf_in_login_form.html
I need add line in my security.yml:
form_login:
# ...
csrf_provider: form.csrf_provider
And change this
<input type="hidden" name="_token" value="{{ csrf_token("intention") }}">
to
<input type="hidden" name="_csrf_token" value="{{ csrf_token("authenticate") }}">
Now I am sure my authentication form si CSRF protected.
CSRF protection is enabled by default, so all you need to do is render your CSRF token in your HTML. You don't need to do anything in your controller.
You have a couple of options:
Do it just like you've done it above
Use {{ form_rest(form) }}, this will render all fields that you haven't rendered yet, including hidden fields like the CSRF token
Either will work fine.

Categories