I am facing CSRF token mismatch problem in laravel. I have checked all notes from stackflow and other sites also but not able to clear this problem.
https://mybestlife.mg-wellness.com/admin/login
user : admin#gmail.com
pass : 1234
you can check the error in console.
Ajax
$("#loginform").on('submit', function(e){
e.preventDefault();
$('button.submit-btn').prop('disabled', true);
$('.alert-info').show();
$('.alert-info p').html('Authenticating...');
$.ajax({
type:"POST",
url:$(this).prop('action'),
data:new FormData(this),
headers: headers,
dataType:'JSON',
contentType: false,
cache: false,
processData: false,
success: function(data) {
console.log(data);
if ((data.errors)) {
$('.alert-success').hide();
$('.alert-info').hide();
$('.alert-danger').show();
$('.alert-danger ul').html('');
for(var error in data.errors) {
$('.alert-danger p').html(data.errors[error]);
}
} else {
// console.log(data)
$('.alert-info').hide();
$('.alert-danger').hide();
$('.alert-success').show();
$('.alert-success p').html('Success !');
window.location.href = data;
}
$('button.submit-btn').prop('disabled',false);
}
});
});
Login function
public function doLogin(Request $request)
{
// print_r($request->all());
$rules = [
'email' => 'required|email',
'password' => 'required'
];
$validator = Validator::make($request->all(), $rules);
if ($validator->fails()) {
return response()->json(array('errors' => $validator->getMessageBag()->toArray()));
}
//--- Validation Section Ends
// Attempt to log the user in
if (Auth::guard('web')->attempt([
'email' => $request->email,
'password' => $request->password,
'status' => 1,
'role' => 1,
'level' => 0
], $request->remember)) {
// if successful, then redirect to their intended location
return response()->json(route('dashboard'));
}
// if unsuccessful, then redirect back to the login with the form data
return response()->json(array('errors' => [
0 => 'Credentials Doesn\'t Match !'
]));
}
Code is working perfectly on localhost and my testing server. But not on the server, i shared above.
Please help me to over come this problem.
Thanks
I think you're missing a header. That's how I've always passed the CSRF token when I use ajax.
The following should be in your resources/js/bootstrap.js file.
window.$ = window.jQuery = require('jquery');
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
});
When trying to login using your site, I couldn't see the X-CSRF-TOKEN header in the request.
I think you didn't set the APP_URL's value correctly. It should be
APP_URL=https://mybestlife.mg-wellness.com instead of what you currently have. (APP_URL=http://localhost/mybestlife_mg_wellness/)
(run php artisan config:clear after changing .env file)
Your site has debug mode on and an unrelated error about the route 'user_login' not existing, this exposes your whole configuration. Please take care to update your database credentials, they are compromised.
This is very important.
Also, rerun the command php artisan key:generate to update the APP_KEY as well.
you have to add #csrf in your form
<form method="post" action="javascript:void(0)" enctype="multipart/form-data">
#csrf
</form>
also add header in jquery
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
also add this meta tag in head of page
<meta name="csrf-token" content="{{ csrf_token() }}">
then you will never get token error .
Add a below line in data array
data:{
_token : {{csrf_field()}},
name:name
}
Related
so I am trying to get the active user off of a fetch request to my backend.
My front end code is:
let apiToken: string | null = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
fetch('http://192.168.0.6:8000/api/testURL', {
method: "POST",
//#ts-ignore
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json, text-plain, */*',
'X-Requested-With': 'XMLHttpRequest',
'X-CSRF-TOKEN': apiToken
},
credentials: 'same-origin',
body: JSON.stringify(data)
})
.then(function(response): void {
console.log(response);
})
.catch(function(err): void {
console.log(err);
});
I have a CSRF token in a meta tag that is generated from csrf_token();
My backend code is:
Route::post('/testURL', function(Request $request)
{
$status = $request->input('status');
$comment = $request->input('comment');
$prospectType = $request->input('prospectType');
$leadId = $request->input('leadId');
$requestUser = $request->user();
return response()->json([
'status' => $status,
'comment' => $comment,
'prospectType' => $prospectType,
'leadId' => $leadId,
'user' => $requestUser
]);
});
The end result from the API call back shows 'user' as null.
I have tried Auth::user() & Auth::id() and they all return null.
I am at a lose and tried using Sanctum to create a validation token which when I added an auth:sanctum middleware it returned a 302 to redirect.
(The same redirect is happening when I apply a vanilla "auth" to a non-Sanctum token'd request).
The request out of all of this!
I want to ensure I have user by ID validation when I send up the request from the frontend to the backend.
I figured it out, the reason the request was not working correctly was the sanctum.php config file did not have my local IP (what I am running my php artisan serve off of) in its 'stateful' array.
I hope this helps anyone! That was five hours of my life.
I've been trying to submit a post request with axios to my projects controller and I keep getting an error 419(unknown status). Even though I'm passing the CSRF through headers to the controller. When I go into my network tab after posting it says:
X-CSRF-TOKEN: undefined
X-Requested-With: XMLHttpRequest
However, when I console.log(window.csrf_token) it returns a token.
This is included in my layout.blade.php
<script type="text/javascript">
window.csrf_token = "{{ csrf_token() }}"
</script>
I define the headers in my app.js for vue:
const axios = require('axios');
axios.defaults.headers.common = {
'X-CSRF-TOKEN': window.csrf_token,
'X-Requested-With': 'XMLHttpRequest',
};
and in my projects.vue here is my axios post request:
Swal.queue([{
title: 'Add a New Project?',
input: 'text',
inputAttributes: {
autocapitalize: 'on'
},
showCancelButton: true,
confirmButtonText: 'Create Project',
showLoaderOnConfirm: true,
preConfirm: (result) => {
return new Promise(function(resolve, reject) {
if (result) {
console.log(result)
axios.post('/api/projects', {title:result})
.then(function(response){
Swal.insertQueueStep({
type: 'success',
title: 'Your project has been created!'
})
resolve();
})
.catch(function(error){
Swal.insertQueueStep({
type: 'error',
title: 'Something went wrong.'
})
console.log(error);
reject();
})
}
});
}
}])
aswell as the store method in ProjectsController.php
public function store()
{
$validated = request()->validate([
'title' => 'required',
]);
Project::create($validated);
return response()->json($validated);
}
Most probably you are setting the CSRF token in your layout file after the usage hence the reason of getting undefined.
Try using the default way, which is by putting a meta tag in your head of the main template like this:
<meta name="csrf-token" content="{{ csrf_token() }}">
Then to use it you may open the given bootstrap.js file where this code is already set:
window.axios = require('axios');
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
let token = document.head.querySelector('meta[name="csrf-token"]');
if (token) {
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
} else {
console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
}
Or if this does not exist, put it in your app.js script or whichever you use on every page.
I am working on Yii 1 application. In my application, there is a CGridView where there is a link, which also fires an ajax request on onclick event. I am sending id as parameter. But the ajax return 400 Bad Request error. Please help me in this matter.
Here is the Gridview:
<h3>Civil Cases</h3>
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id'=>'notifications-grid',
'dataProvider'=>$dataProvider_civil,
'summaryText' => false,
'columns'=>array(
array(
'name' => 'case_id',
'type' => 'raw',
'value' => 'CHtml::link(CHtml::encode($data->case_id),array("civilcases/view","id"=>$data->case_id), array("onclick"=>"js:readNotification($data->id)"))'
),
array(
'name' => 'caseno',
'type' => 'raw',
'value' => 'CHtml::link(CHtml::encode($data->caseno),array("civilcases/view","id"=>$data->case_id), array("onclick"=>"js:readNotification($data->id)"))'
),
'date_filing',
'next_date',
'panel_lawyer_id',
),
));
?>
here is the script:
<script>
var readNotification = function(id) {
console.log("button clicked with ID: "+id); //getting id here
$.ajax({
type:'POST',
url:'<?php echo Yii::app()->createUrl("notifications/readNotification");?>',
data: {id: id}
});
};
</script>
here is the controller:
public function actionReadNotification(){
echo $_POST['id'];
}
added readNotification function to the accessRules. When clicking on the link new page is loading but ajax request shows error.
Try adding the csrf token inside your data with your ajax request.
<script>
var readNotification = function(id) {
console.log("button clicked with ID: "+id); //getting id here
$.ajax({
type:'POST',
url:'<?php echo Yii::app()->createUrl("notifications/readNotification");?>',
data: {id: id,<?=
Yii::app()->request->csrfTokenName?>:<?=Yii::app()->request->csrfToken?>,}
});
};
</script>
You can also disable the csrftoken by adding the below in the beforeAction()
public function beforeAction($action) {
if($action->id=='readnotification'){
$this->enableCsrfValidation = false;
}
return parent::beforeAction($action);
}
but this is not recommended way of doing the work.
EDIT
i mistakenly added Yii::$app->request instead of Yii::app()->request as the first one is for Yii2 and not for Yii1 please change it to
<?=Yii::app()->request->csrfTokenName?>:<?=Yii::app()->request->csrfToken?>
and make sure you have the request component with the following configurations
'components'=>array(
.
.
.
'request'=>array(
'enableCookieValidation'=>true,
'enableCsrfValidation'=>true,
'csrfTokenName'=>'_my-token',
),
Note : you can change the _my-token to any other name you like
I am working in laravel 5. and using blade and ajax for upload image.
Every thing was working fine unless I inserted validation code in store function inside controller. Getting server error:
POST http://localhost:8000/imgC 500 (Internal Server Error)
I guess there is something wrong with url inside ajax or in routes, I am using Restfull Controller.
image.blade.php
{{Form::open(array('url' => 'imgC', 'method' => 'post','files'=>true, 'id'=>'upload_form'))}}
Title: {{Form::text('title')}}
Image: {{Form::file('image')}}
{{Form::submit('submit',['id' => 'btnAddProduct'])}}
{{Form::close()}}
ImageController.php:
public function store(Request $request)
{
$validator = Validator::make($request->all(), [
'name' => 'required|max:255',
]);
if ($validator->fails()) {
return "error";
}
$destinationpath = public_path() . '/img/';
$image=$request->input('image');
$filename=$request->file('image')->getClientOriginalName();
$request->file('image')->move( $destinationpath,$filename );
$img= new Image;
$img->name= $request->input('title');
$img->picture_path=$filename;
$saveflag=$img->save();
if($saveflag){
return Response::json(['success' => $saveflag, 'file' => asset($destinationpath.$filename)]);
}
}
AJAX function:
$(document).ready(function() {
$('#upload_form').submit(function (event) {
event.preventDefault();
$.ajax({
url: '/imgC',
data: new FormData($(this)[0]),
type: "POST",
processData: false,
contentType: false
}).done(function (response) {
console.log(response);
$("#success").show();
setTimeout(function() { $("#success").hide(); }, 5000);
});
});
});
route.php:
Route::resource('imgC', 'ImageController');
What am I doing wrong here?
I looked into the server log files and figured it out.
There was error with validation after adding Use Validator; in Image controller, problem solved
I'm getting 422 Unprocessable Entity error even when I'm submitting my form via Ajax.
My javascript file
$.ajaxSetup({
headers: {
'X-XSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$('.keywords-plan-form').submit(function(event) {
event.preventDefault();
$.ajax({
url: '/laravel/public/keywordsplans',
type: 'POST',
data: $(this).serialize(),
success: function(data){
alert(data);
// success logic
},
error: function(data){
// Error...
var errors = $.parseJSON(data.responseText);
console.log(errors);
$.each(errors, function(index, value) {
});
}
});
});
as you can see I added X-XSRF-TOKEN****strong text to ajax header.
This is my '' tag
<meta name="csrf-token" content="{{ csrf_token() }}">
my Form Data in chrome debuger
_token:5j6DGhhTytbIRB1GrW9Wml9XrOxmKjgE9RiGa4Gf
date:
keyword[0]:Lorem ipsum
keyword[1]:Is dolor amet
keyword[2]:plumber tampa
Request Headers
X-XSRF-TOKEN:5j6DGhhTytbIRB1GrW9Wml9XrOxmKjgE9RiGa4Gf
.....
am I doing something wrong or forgetting something?
I don't think that csrf token is the issue here. If it were you would get TokenMissmatchException and not Unprocessable Entity.
Do you happen to have a request validator in your Controller like this?
$validator = Validator::make($request->all(), [
'username' => 'required|max:30|min:6|unique:users',
'email' => 'required|email|max:50|unique:users',
'password' => 'required|confirmed|min:6',
]);
If so maybe you can do something like this:
if ($validator->fails()) {
if($request->ajax())
{
return response()->json(array(
'success' => false,
'message' => 'There are incorect values in the form!',
'errors' => $validator->getMessageBag()->toArray()
), 422);
}
$this->throwValidationException(
$request, $validator
);
}
After that you can catch validation errors in your ajax error handler like this:
$('.keywords-plan-form').submit(function(event) {
event.preventDefault();
$.ajax({
url: '/laravel/public/keywordsplans',
type: 'POST',
data: $(this).serialize(),
success: function(data){
alert(data);
// success logic
},
error: function(jqXhr, json, errorThrown){// this are default for ajax errors
var errors = jqXhr.responseJSON;
var errorsHtml = '';
$.each(errors['errors'], function (index, value) {
errorsHtml += '<ul class="list-group"><li class="list-group-item alert alert-danger">' + value + '</li></ul>';
});
//I use SweetAlert2 for this
swal({
title: "Error " + jqXhr.status + ': ' + errorThrown,// this will output "Error 422: Unprocessable Entity"
html: errorsHtml,
width: 'auto',
confirmButtonText: 'Try again',
cancelButtonText: 'Cancel',
confirmButtonClass: 'btn',
cancelButtonClass: 'cancel-class',
showCancelButton: true,
closeOnConfirm: true,
closeOnCancel: true,
type: 'error'
}, function(isConfirm) {
if (isConfirm) {
$('#openModal').click();//this is when the form is in a modal
}
});
}
});
});
And see the messages in the
modal message
Maybe someone will come in handy.
422 Unprocessable Entity
is default error by validator laravel
vendor/laravel/framework/src/Illuminate/Validation/Validator.php
If fails validate params, then throught Exception ValidationException
vendor/laravel/framework/src/Illuminate/Validation/ValidationException.php
where default status = 422
And therethore all your ajax responses with non validate forms will be with status = 422
I have solved this issue :
public function register(\Illuminate\Http\Request $request) {
if ($this->validator($request->all())->fails()) {
$errors = $this->validator($request->all())->errors()->getMessages();
$clientErrors = array();
foreach ($errors as $key => $value) {
$clientErrors[$key] = $value[0];
}
$response = array(
'status' => 'error',
'response_code' => 201,
'errors' => $clientErrors
);
} else {
$this->validator($request->all())->validate();
$user = $this->create($request->all());
$response = array(
'status' => 'success',
'response_code' => 200
);
}
echo json_encode($response);
}
Whoever is still looking for the answer, if you are using Lumen make sure the Request object is a type of Illuminate\Http\Request and not the default one from Lumen.
```function create(Request $request){