i'm using ajax to send email so i my problem is if i dont have
{!! csrf_field() !!}
in view i will get the token missmatch error.If i add input hidden token in view i will get this error
Swift_RfcComplianceException in MailboxHeader.php line 348: Address in
mailbox given [] does not comply with RFC 2822, 3.6.2.
How can i fix it.Thanks for help.
here it's view
<form action="{{ url('/findpass')}}" method="POST" id="forgotpassForm">
{!! csrf_field() !!}
<div class="form-group">
<input class="form-control input-lg" placeholder="E-mail" name="emailForgot" type="email" id="emailForgot" required>
</div>
<input type="submit" class="btn btn-lg btn-primary btn-block" id="forgotpassBtn" value="Send email">
</form>
Ajax
$(document).ready(function() {
$('#forgotpassBtn').click(function() {
event.preventDefault();
var email=$("#emailForgot").val();
var _token = $("input[name='_token']").val();
$.ajax({
url: '/findpass',
type: 'POST',
data:{
email:email,
_token : _token
},
success:function(data) {
alert(data.mess);
$("#forgotpass")[0].reset();
},
error:function() {
alert("Error");
}
});
});
});
Controller
public function resetPass()
{
$emailForgot=Input::get('emailForgot');
$user= User::where('email', '=' , $emailForgot)->first();
$data=['username'=>$user -> username,'email'=>$user -> email,'token'=>$user -> remember_token];
Mail::send('ui.mail.reset',$data, function ($m) use ($user) {
$m->from('ngohungphuc95#gmail.com', 'Reset password');
$m->to($user->email, $user->full_name)->subject('Email reset password');
});
return response()->json(array('mess'=>'Mail send'));
}
Add the csrf without blade and add an id by yourself. Get the value of csrf value by id using jquery. Here is how you can do this.
Change {!! csrf_field() !!} to:
<input type="hidden" name="_token" value="{{ csrf_token() }}" id="token"/>
And Change this line of ajax code:
var _token = $("input[name='_token']").val();
To:
var _token = $('#token').val();
May be this is not the best way. But I solved my problem with this procedure.
You could also add a global csrf token to all ajax calls like this
$(document).ready(function(){
$.ajaxSetup({
headers: { 'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content') },
});
});
Then just override the tokensMatch() method of the VerifyCsrfToken token to also look for the ajax header
protected function tokensMatch($request)
{
// If request is an ajax request, then check to see if token matches token provider in
// the header. This way, we can use CSRF protection in ajax requests also.
$token = $request->ajax() ? $request->header('X-CSRF-Token') : $request->input('_token');
return $request->session()->token() == $token;
}
After this all your ajax calls will automatically pass csrf checks and be secure.
Swift_RfcComplianceException in MailboxHeader.php line 348: Address in mailbox given [] does not comply with RFC 2822, 3.6.2.
The above error is because you haven't configured a from address in config/mail.php. It is set to null by default, but should be a valid email address:
'from' => ['address' => 'user#example.com', 'name' => null],
Related
I have a user schedule record that I can update easily without one form field called disabled_dates. disabled_dates is setup to store an array of dates a user can add one at a time. What I did was add a form field with its own button using a javascript function disable() in the onclick attribute to update the record.
<div class='input-group text-center'>
{!! Form::text('disabled_dates', null , ['class' => 'form-control text-center datetimepicker15', 'id' => 'disable_date', 'placeholder' => '']) !!}
<span class="input-group-btn">
<button type="button" onclick="disable();" class="btn btn-fab btn-round btn-success">
<i class="material-icons">add</i>
</button>
</span>
Then created the disable(); like so
function disable() {
var CSRF_TOKEN = '{{ csrf_token() }}';
var disabled_date = document.getElementById('disable_date').value;
$.ajax({
type:'PUT',
url:'/schedule',
data:{_token: CSRF_TOKEN, blocked_date: disabled_date},
success:function(response) {
console.log(response);
}
});
}
The controller function used is
public function add_blocked_day(Request $request)
{
$schedule = User::find(auth()->user()->id)->schedule;
$current_blocked_dates = $schedule->disabled_dates;
$schedule->disabled_dates = $current_blocked_dates. ','.$request->blocked_date;
$schedule->save();
exit;
}
All Im getting now is too many redirects. The solution Im thinking is to seperate disabled_dates and enclose in its own form tags, because its calling the original form route somehow
I got it to work by changing the function to this
$(document).on("click", ".add-day" , function() {
var CSRF_TOKEN = '{{ csrf_token() }}';
var disabled_date = document.getElementById('disable_date').value;
$.ajax({
type:'POST',
url:'schedule/blocked-day',
data:{_token: CSRF_TOKEN, blocked_date: disabled_date},
success:function(response) {
console.log(response);
}
});
});
i have a login form to login a user i want to know about how to get laravel response in ajax success function. if submit the form i was got a object('status':'msg') in http://127.0.0.1:8000/login page. but i want to just redirect user correct page after login with macing alert. please help me to learn laravel with ajax function.
form
<form id="loginForm" method="POST" action="{{ route('login') }}">
#csrf
<input id="email" type="email" class="form-control name="email" value="{{ old('email') }}"
required autocomplete="email" autofocus>
<input id="password" type="password" class="form-control name="password" required
autocomplete="current-password">
<button type="submit" class="btn btn-primary">LOGIN</button>
</form>
ajax: after document ready
$('#loginForm').submit(function(e){
e.preventDefault();
var formInput = $(this);
$.ajax({
type:'POST',
url: 'login',
data: formInput.serialize(),
dataType: 'json',
cache: false,
success:function(status){
if(status== "success"){
alert("your in");
}
},
error:function(status){
if(status== "error"){
alert("no data found");
}
}
})
});
Route:
Route::post('login','loginController#login')->name('loginData');
Controller:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Auth;
use Session;
class loginController extends Controller
{
public function login(Request $request){
$credentials = $request->only('email', 'password');
if (Auth::attempt($credentials)) {
// print_r($request->all());
session()->put('role', Auth::user()->Role);
$request->session()->flash('message', 'New customer added successfully.');
$request->session()->flash('message-type', 'success');
return response()->json(['status'=>'success']);
return back();
}else{
$request->session()->flash('message', 'you have entered an invalid email address or password. please try again');
$request->session()->flash('message-type', 'danger');
return response()->json(['status'=>'error']);
return back();
}
}
}
You can return more data in your AJAX response than just a status. If you wanted to, you could also return a location to redirect to like:
return response()->json([
'status' => 'success',
'redirect' => '/user/dashboard'
]);
Then in your javascript, when you get success, you can then do:
success: function(response) {
if(response.status === "success") {
alert("your in");
window.location.href = response.redirect;
}
},
I've upgraded my app from Laravel 4.2 to Laravel 5.3. On an index page listing citations, I have an AJAX modal form to edit or view the login credentials for the citation. This was working fine in Laravel 4.2, but I cannot for the life of me get it to work in 5.3. After about 5 hours Googling and trying different things, I thought I would post it here so that someone way more experienced than me can point me in the right direction.
Here's the link on the index page:
<a style="cursor: pointer; " title= "Login Credentials" data-loopback="cit-pg-1" data-citationid="1079" class="getCitationdetails"><span class="glyphicon glyphicon-lock " title="Login Credentials"></span></a>
And here's the JavaScript:
<script type="text/javascript">
$(document).on('click','.getCitationdetails',function(){
var citationid = $(this).data('citationid');
var loopback = $(this).data('loopback');
$.ajax({
url : '/citation-password',
type:'post',
data : {citationid :citationid, loopback :loopback},
success:function(resp){
$('#AppendLoginDetails').html(resp);
$('#LoginCredentialsModal').modal('show');
$('.loadingDiv').hide();
},
error:function(){
alert('Error');
}
})
})
Here's my route:
Route::match(['get', 'post'], '/citation-password', 'CitationsController#citationpassword');
And here's the Controller method that generates the form on get and saves the data on post:
public function citationpassword()
{
if (Request::ajax()) {
$data = Request::all();
if (!$data['citationid']) {
return redirect('/citations')
->with('flash-danger', 'Missing citation id for Login credentials form!!');
}
// Save loopback variable if we have it in order to return user to the page where they came from; default return location is citations
$loopback = 'citations';
if (array_key_exists("loopback", $data)) {
$loopback = $data['loopback'];
}
$getcitationdetails = Citation::where('id', $data['citationid'])->select('id', 'site_id', 'username', 'password', 'login_email', 'login_notes')->first();
$getcitationdetails = json_decode(json_encode($getcitationdetails), true);
$getsitedetails = Site::where('id', $getcitationdetails['site_id'])->select(
'id',
'directory_username',
'directory_password',
'security_questions',
'email_account',
'email_account_password',
'email_account_name',
'google_user',
'google_pwd',
'name_of_google_account'
)->first();
$getsitedetails = json_decode(json_encode($getsitedetails), true);
$response ="";
$response .= '<form action="'.url('/citation-password').'" method="post">
<div class="modal-body">';
if (!empty($getsitedetails['directory_username'])) {
$response .= '<div class="form-group">
<label for="recipient-name" class="col-form-label">Default login credentials for this site:</label>
<p>Username: '.$getsitedetails['directory_username'].'
<br />Password: '.$getsitedetails['directory_password'].'
<br />Email account: '.$getsitedetails['email_account'].'
<br />Email password: '.$getsitedetails['email_account_password'].'
<br />Name on email account: '.$getsitedetails['email_account_name'].'
<br />Default security questions: '.$getsitedetails['security_questions'].'</p>
<p>Gmail account: '.$getsitedetails['google_user'].'
<br />Gmail password: '.$getsitedetails['google_pwd'].'
<br />Name on Gmail account: '.$getsitedetails['name_of_google_account'].'</p>
</div>';
}
$response .= '
<input type="hidden" name="_token" value="'.csrf_token() .'" />
<input type="hidden" name="citation_id" value="'.$data['citationid'].'" />
<input type="hidden" name="loopback" value="'.$loopback.'" />
<div class="form-group">
<label for="recipient-name" class="col-form-label">Username:</label>
<input type="text" class="form-control" name="username" value="'.$getcitationdetails['username'].'" autocomplete="off">
</div>
<div class="form-group">
<label for="message-text" class="col-form-label">Password:</label>
<input type="text" class="form-control" name="password" value="'.$getcitationdetails['password'].'" autocomplete="off">
</div>
<div class="form-group">
<label for="message-text" class="col-form-label">Login email used:</label>
<input type="text" class="form-control" name="login_email" value="'.$getcitationdetails['login_email'].'" autocomplete="off">
</div>
<div class="form-group">
<label for="message-text" class="col-form-label">Login notes:</label>
<textarea class="form-control" style="height:130px;" name="login_notes">'.$getcitationdetails['login_notes'].'</textarea>
</div>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-success" id="success">Save</button>
<button type="button" class="btn btn-danger" data-dismiss="modal" aria-hidden="true">Cancel</button>
</div>
</form>';
return $response;
} else {
// The popup modal has posted back here; process the data
$data = Request::all();
// Handle & translate loopback; returning user to the page where they came from
$loopback = 'citations';
if ($data['loopback']) {
$loopback = $data['loopback'];
// Translate pages it came from
$trackLoopback = new trackLoopback();
$loopback = $trackLoopback->translate($loopback);
}
$updatecitation = Citation::find($data['citation_id']);
$updatecitation->username = $data['username'];
$updatecitation->password = $data['password'];
$updatecitation->save();
return redirect($loopback)
->with('flash-success', 'Login credentials have been updated successfully!');
}
}
In an effort to isolate the error, I even simplified the form in the controller like this:
public function citationpassword()
{
if (Request::ajax()) {
return '<p>This is the modal form!</p>';
} else {
// The popup modal has posted back here; process the data
$data = Request::all();
// Handle & translate loopback; returning user to the page where they came from
$loopback = 'citations';
if ($data['loopback']) {
$loopback = $data['loopback'];
// Translate pages it came from
$trackLoopback = new trackLoopback();
$loopback = $trackLoopback->translate($loopback);
}
$updatecitation = Citation::find($data['citation_id']);
$updatecitation->username = $data['username'];
$updatecitation->password = $data['password'];
$updatecitation->save();
return redirect($loopback)
->with('flash-success', 'Login credentials have been updated successfully!');
}
}
and also simplified the route to this:
Route::get('/citation-password', 'CitationsController#citationpassword');
but all I get when I click the link is a popup notice, "Error."
I'm not experienced with AJAX. How do I get the form to display in Laravel 5.3?
And/or, how can I change the JavaScript function so that it shows the actual error instead of the "Error" notice? (I tried a number of methods I found on StackOverflow to display errors but all of them resulted in NO error notice; just a blank page. And, I've not been successful at getting my Firefox debugger to show the errors either.)
Thanks!
The correct way to debug the JavaScript is to post the errors this way:
<script type="text/javascript">
$(document).on('click','.getCitationdetails',function(){
var citationid = $(this).data('citationid');
var loopback = $(this).data('loopback');
$.ajax({
url : '/citation-password',
type:'post',
data : {citationid :citationid, loopback :loopback},
success:function(resp){
$('#AppendLoginDetails').html(resp);
$('#LoginCredentialsModal').modal('show');
$('.loadingDiv').hide();
},
error: function(xhr, ajaxOptions, thrownError) {
alert(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);
}
})
})
Once you do so, you will see that the error has to do with missing CsrfToken for the form. [The actual error message is from the Laravel framework: Illuminate\Session\TokenMismatchException: in file /home/reviewsites/moxy53/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php on line 6] Since both the get and post verbs use the same route, Laravel is requiring the CsrfToken before the form with the Csrf field gets generated.
It is possible (but NOT recommended!) to exclude this route from CSRF protection by editing App\Http\Middleware\VerifyCsrfToken.php with the following exception:
/**
* The URIs that should be excluded from CSRF verification.
*
* #var array
*/
protected $except = [
'/citation-password',
];
However, a much better approach is to add the token. It is correct that since you are using a post method to send the data values to the controller, you cannot use the controller to generate the token field in the form. Hence, the solution is to take the html out of the controller and put it in the blade. These lines:
$response .= '<form action="'.url('/citation-password').'" method="post">
<div class="modal-body">';
...
</div>
</form>';
should not be in the $response generated by the controller, but should instead be in the modal div in the blade itself. THEN, you can add the CSRF field in the blade thus:
<form action="{{url('/citation-password')}}" method="post">
{{ csrf_field() }}
<div class="modal-body" id="AppendLoginDetails">
</div>
</form>
I'm trying to send data to back-end and i'm getting 404 error with this explanation in network tab:
"message": "",
"exception": "Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException",
Route
Route::middleware('verified')->group(function () {
Route::post('/snaptoken/{id}', 'Admin\PayController#token')->name('securepaymentnow');
});
Controller
public function token(Request $request, $id)
{
//Find project
$project = Project::findOrFail($id);
//rest of data
}
Blade
//form and button
<form id="payment-form" method="POST" action="{{route('securepaymentnow', $project->id)}}">
#csrf
<input type="hidden" name="result_type" id="result-type" value="">
<input type="hidden" name="result_data" id="result-data" value="">
</form>
<button class="btn-sm bg-success pay-button" data-id="{{$project->id}}" type="submit"><i class="fas fa-fas fa-shield-alt"></i> Secure Payment</button>
//javascript
$('.pay-button').click(function (event) {
$.ajaxSetup({
headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') }
});
event.preventDefault();
// $(this).attr("disabled", "disabled");
var prdfoId = $(this).data('id');
$.ajax({
url: '{{url("/securepaymentnow")}}/'+encodeURI(prdfoId),
type: "POST",
cache: false,
success: function(data) {
var resultType = document.getElementById('result-type');
var resultData = document.getElementById('result-data');
}
});
});
Any idea?
.........................................................................................................................
if you are using url() function, you should use the {{ url('/snaptoken') }}.
But if you want to use the "name" from the "securepaymentnow", use route() function with this example {{ route('securepaymentnow', $theId) }}.
Both should works.
Refer Laravel NamedRoute for details.
When I submit the form, I get this error and the page automatically reloads, but the url in the browser then shows my route and content that I posted in the form. Then, if I go ahead and submit again without reloading the page it works just fine. Could it be that I'm not posting the token itself? I have added the meta tag to the head.
<meta name="csrf-token" content="{{ csrf_token() }}" />
JS:
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$('#postForm').submit(function(){
var body = $('#postbody').val();
var profileId = $('#user_id').text();
$.ajax({
type: "POST",
url: "/post/"+profileId,
data: {post:body, profile_id:profileId},
success: function(data) {
console.log(data);
}
});
});
Route:
Route::post('/post/{id}', [
'uses' => '\App\Http\Controllers\PostController#postMessage',
'as' => 'post.message',
'middleware' => ['auth'],
]);
Controller:
public function postMessage(Request $request, $id)
{
if(Request::ajax())
{
$this->validate($request, [
'post' => 'required|max:1000',
]);
$newMessage = Auth::user()->posts()->create([
'body' => $request->input('post'),
'profile_id' => $id
]);
}
}
View:
<form role="form" action="#" id="postForm">
<div class="feed-post form-group">
<textarea class="form-control feed-post-input" id="postbody" name="post"></textarea>
<div class="btn-bar">
<button type="submit" class="btn btn-default btn-post"></button>
</div>
</div>
<input type="hidden" name="_token" value="{{ csrf_token() }}"/>
</form>
UPDATE:
So, the log says that "Request::ajax() should not be called statically" in my controller. I removed that code and it works fine now. However, I want to know if removing it is ok to do of if there's a better way to resolve this. Thanks!
ANSWER: It works by changing
if (Request::ajax()){
// code...
}
to
if ($request->ajax()){
// code...
}
Change Request::ajax() to $request->ajax()
You are doing an AJAX post – you are not supposed to be redirected anywhere at all. If there is an error – you should only see it in Developers Tools in your browser.
Try adding:
$('#postForm').submit(function(e) {
e.preventDefault();
...
}
So that browser doesn't post the form instead of your AJAX call. Also try fixing your header case: X-CSRF-TOKEN to X-CSRF-Token
Also, your postMessage() method doesn't return anything at all. You should probably notify the user of the result there or just return $newMessage.