Laravel 5 POST data to DB - laravel

i want to insert data to db using POST request
table food_directory
id (auto incremenat)
name
fructose
polylos
fructan
public function postDirec()
{
if (\Request::ajax()) {
$FodMaps = \Request::get('name');
\DB::table('food_directory')->insert([
'food_directory' => $FodMaps,
]);
}
}
Route
Route::post('postDirec', 'FodMapController#postDirec');
this will return Tokenmismatch issue.. please advice

You need to add the CSRF-token in your form, by adding this line somewhere between your form's opening and closing tag:
{!! csrf_field() !!}

Goto App\Http\Kernel.php
And comment out this line
\App\Http\Middleware\VerifyCsrfToken::class,
It should be Line 20 in that file if you haven't made any other changes.

if you want to disable csrf protection on certain routes you can to this approach.
in the app/Http/Middlewares/VerifyCsrfToken.php modify handle method to
//disable CSRF check on following routes
$skip = [
'/your-uri/you-want-to-disable-protection-for',
route('or_some_route')
];
foreach ($skip as $route) {
if ($request->is($route)) {
return $this->addCookieToResponse($request, $next($request));
}
}
return parent::handle($request, $next);
Put uri you want to disable into the skip array. It will then call the parent's class addCookieToResponse method that will set CSRF token to the cookie and request would be treated as protected.

Related

vue axios delete request not working in laravel 7

Vue component
methods: {
removeCategory(index) {
if (confirm('Are you sure ?')) {
let id = this.categories[index].id;
console.log("ID="+id);
if (id > 0) {
axios.delete('/api/categories/' + id);
}
this.categories.splice(index, 1);
}
},
Routes Api
Route::delete('/categories/{category}', 'CategoryController#destroy');
Controller
public function destroy(Category $category)
{
$this->authorize('delete', $category);
$category->delete();
return $category;
}
Put request is working fine for inserting and updating data, but DELETE request is not able to delete data from the database.
Thanks
Laravel check CSRF token.
You need to add X-CSRF-TOKEN in the request header
You can read this doc : https://laravel.com/docs/7.x/csrf#csrf-x-csrf-token
If you haven't found the answer yet, quick fix as:
Remove the model binding in your Controller.
Grab specific category with an id.
Authorize and delete it.
(no need to modify the Component and the Route)

How to refresh csrf token on each request without session expire issue in Laravel 5.4

I want to refresh the CSRF token on each post request in Laravel 5.4
Added code from below SO link, still not helping
How to generate new CSRF Token for each user request in Laravel?
protected function addCookieToResponse($request, $response)
{
$response = next($request); // process petition
$request->session()->regenerateToken(); // regenerate token
return $response; // send response
}
Try this instead
protected function addCookieToResponse($request, $response)
{
session()->regenerateToken();
return parent::addCookieToResponse($request, $response);
}
Although this is not advised as it will break usuability, csrf_token is outputted before the new token is refreshed causing mismatch exception, would only work if you're extracting the token from the cookie with Javascript and not using the blade #csrf directive or csrf_token() helper function

Delete Method in Axios, Laravel and VueJS

I am trying to send a delete request via axios to laravel as follow:
axios.delete('api/users/' + this.checkedNames)
.then((response) => {
console.log(response)
}, (error) => {
// error callback
})
Now from axios documentation I read that for delete request we should be using a configObject so the above could be rewritten as so:
axios.delete('api/users/', {params: {ids:
this.checkedNames})
.then((response) => {
console.log(response)
}, (error) => {
// error callback
})
I have then Route::resource('users', 'UsersController'); in api.php so the default route for deleting is:
DELETE| api/users/{user}| users.destroy
and the controller's method is:
|App\Http\Controllers\UsersController#destroy
I am able to delete as expected a user when I pass a single id let's say api/users/12, it gets deleted correctly but when I try to pass the array above things get complicated.
if I try as per axios documentation axios.delete('api/users/', {params: {id: this.checkedNames}}) it looks I am sending this http://lorillacrud.dev/api/users?id[]=21&id[]=20 but I get a 405 method not allowed.
if I try axios.delete('api/users/' + this.checkedNames ) I get http://lorillacrud.dev/api/users/20,21 so in my destroy method I could grab the ids and delete, but I am wondering if this is the correct way to do it?
update
I seemed I made it work but I am not understanding so any help still appreciated to make a sense of what I am actually making work!
So, if change to:
axios.delete('api/users/destroy', {params: {'id': this.checkedNames})
and in my destroy method:
if ($request->id) {
foreach ($request->id as $id) {
User::destroy($id);
}
}
User::destroy($id);
}
So...
// not deletes the user
axios.delete('api/users/destroy', {params: {id: id}})
// ok deletes the users when using request->id in a for loop in the destroy laravel method.
axios.delete('api/users/destroy', {params: {ids: this.checkedNames}})
// ok deletes one user
axios.delete('api/users/' + id)
sorry guys but I have a lot of confusion why and what !!!
The route name is user.destroy why does it work when I pass an array and it does not when I pass a single value, why viceversa the route with method delete will not delete when pass an array ???
Any difference between using api/users/destroy vs api/users only?
Thanks for any help on this!
I also experienced the same problem. This works for me:
deletePost: function(id) {
axios.post('/posts/'+id,{_method: 'delete'})
}
Using axios.post() instead of axios.delete, and sending _method "delete"
It is because of the method signatures. The default delete route when using Resource expects a single parameter. So when doing:
axios.delete('api/users', {params: {'id': this.checkedNames})
you are missing a required parameter. The route definition is
Route::delete('api/users/{id}', 'UserController#destroy');
// You are missing `id` here. So it won't work.
Usually, if you are going to stray away from the default behavior, it is recommended to create your own function. So you could leave the default destroy($id) function as is to delete a single entry and write a new function that will delete many. Start by adding a route for it
Route::delete('api/users', 'UserController#deleteMany');
Then define the function to handle it
public function deleteMany(Request $request)
{
try
{
User::whereIn('id', $request->id)->delete(); // $request->id MUST be an array
return response()->json('users deleted');
}
catch (Exception $e) {
return response()->json($e->getMessage(), 500);
}
}
To summarise, your problem came from route definition. Your route from Axios did not match the route definition from Laravel, hence the 405.
I was having issue to send data as model while making delete request. I found a fix as follows:
deleteCall (itemId, jsonModel) {
return api.delete(`/users/${itemId}/accounts/`, {data: jsonModel})
},
Deleting users in array
Other good option, is to convert javascript array to string, and pass it has the required parameter, instead of passing object. Here the example:
In Vue.js 2.5.17+
//Use the javascript method JSON.stringify to convert the array into string:
axios.delete('api/users/' + JSON.stringify(this.checkedNames))
In Laravel 5.3+
//Resource default route (you don't need to create, it already exists)
Route::delete('api/users/{id}', 'UserController#destroy');
//In laravel delete method, convert the parameter to original array format
public function destroy($id)
{
User::destroy(json_decode($id); //converting and deleting users in array 'id'
}
Deleting single user by id
Just pass the id. You don't need to convert it.
In Vue.js 2.5.17+
axios.delete('api/users/' + id)
In Laravel 5.3+
You can name the parameter as you wish: user, id, item ,...
In Laravel 5.6+ < is named as $id //this can be the id or the user object
In Laravel 5.7+ > is named as $user //this can be the id or the user object
public function destroy($id)
{
User::destroy($id);
}
axios.post('/myentity/839', {
_method: 'DELETE'
})
.then( response => {
//handle success
})
.catch( error => {
//handle failure
})
https://www.mikehealy.com.au/deleting-with-axios-and-laravel/

Laravel 5: Calling routes internally

Is there a way, in Laravel 5, to call routes internally/programmatically from within the application? I've found a lot of tutorials for Laravel 4, but I cannot find the information for version 5.
Using laravel 5.5, this method worked for me:
$req = Request::create('/my/url', 'POST', $params);
$res = app()->handle($req);
$responseBody = $res->getContent();
// or if you want the response to be json format
// $responseBody = json_decode($res->getContent(), true);
Source:
https://laracasts.com/discuss/channels/laravel/route-dispatch
*note: maybe you will have issue if the route you're trying to access
has authentication middleware and you're not providing the right credentials.
to avoid this, be sure to set the correct headers required so that the request is processed normally (eg Authorisation bearer ...).
UPDATE: i've tried this method with laravel 8 and it works but if you're using PHP version 8.0 you might need to call opcache_reset(); before this line $req = Request::create('/my/url', 'POST', $params); to avoid an error.
see guzzlehttp/guzzle dosn't work after update php to php 8 for more info
You may try something like this:
// GET Request
$request = Request::create('/some/url/1', 'GET');
$response = Route::dispatch($request);
// POST Request
$request = Request::create('/some/url/1', 'POST', Request::all());
$response = Route::dispatch($request);
You can actually call the controller that associates to that route instead of 'calling' the route internally.
For example:
Routes.php
Route::get('/getUser', 'UserController#getUser');
UserController.php
class UserController extends Controller {
public function getUser($id){
return \App\User::find($id);
};
}
Instead of calling /getUser route, you can actually call UserController#getUser instead.
$ctrl = new \App\Http\Controllers\UserController();
$ctrl->getUser(1);
This is the same as calling the route internally if that what you mean. Hope that helps
// this code based on laravel 5.8
// I tried to solve this using guzzle first . but i found guzzle cant help me while I
//am using same port. so below is the answer
// you may pass your params and other authentication related data while calling the
//end point
public function profile(){
// '/api/user/1' is my api end please put your one
//
$req = Request::create('/api/user/1', 'GET',[ // you may pass this without this array
'HTTP_Accept' => 'application/json',
'Content-type' => 'application/json'
]);
$res = app()->handle($req);
$responseBody = json_decode($res->getContent()); // convert to json object using
json_decode and used getcontent() for getting content from response
return response()->json(['msg' =>$responseBody ], 200); // return json data with
//status code 200
}
None of these answers worked for me: they would either not accept query parameters, or could not use the existing app() instance (needed for config & .env vars).
I want to call routes internally because I'm writing console commands to interface with my app's API.
Here's what I did that works well for me:
<?php // We're using Laravel 5.3 here.
namespace App\Console;
use App\MyModel;
use App\MyOtherModel;
use App\Http\Controllers\MyController;
use Illuminate\Console\Command;
class MyCommand extends Command
{
protected $signature = 'mycommand
{variable1} : First variable
{variable2} : Another variable';
public function handle()
{
// Set any required headers. I'm spoofing an AJAX request:
request()->headers->set('X-Requested-With', 'XMLHttpRequest');
// Set your query data for the route:
request()->merge([
'variable1' => $this->argument('variable1'),
'variable2' => $this->argument('variable2'),
]);
// Instantiate your controller and its dependencies:
$response = (new MyController)->put(new MyModel, new MyOtherModel);
// Do whatever you want with the response:
var_dump($response->getStatusCode()); // 200, 404, etc.
var_dump($response->getContent()); // Entire response body
// See what other fun stuff you can do!:
var_dump(get_class_methods($response));
}
}
Your Controller/Route will work exactly as if you had called it using curl. Have fun!

Laravel Except Token Mismatch Error

My URL
http://laravel/tr/order/fp1/success
VerifyCsrfToken Except .
protected $except = [
'order/*'
];
But i have Token Mismatch Error.
Update:
I'm posting data to external webpage (Bank Server) And They are posting to my site.
As per the Op's comment it seems that the request is coming from external site where we can't generate csrf tokens from our application.
So, there is two possible solutions
Method 1 :
The request should get the csrf token from the application in prior request and then send the request with token
Method 2 :
You should attach a parameter with incoming request and have this inside the app\Http\Middleware\VerifyCsrfToken.php
$paramExist= $request->yourSecretParam;
#return parent::handle($request, $next);
if(isset($paramExist))
{
$yourSpecialkey ='a2$%$'; #This to check whether the param has the value that you set
if($paramExist==$yourSpecialKey)
{
return $next($request);
}
else
{
return parent::handle($request, $next);
}
}
else
{
return parent::handle($request, $next);
}
By having this you can check whether the request matches not with the parameter value that the external application has.
Hope, this helps you
I solve the problem.
In Except Property we have to write URI. But i didn't write language path.
protected $except = [
'tr/order/*'
];
If i write language path. It is working. But hardcoding language path is not logical.
And i override shouldPassThrough of BaseVerifier in Laravel.
protected $except = [
'order/*',
];
protected function shouldPassThrough($request)
{
foreach ($this->except as $except) {
if ($request->is(trim(Lang::locale().'/'.$except, '/'))) {
return true;
}
}
return false;
}
We add Lang::locale().'/'
Now we can use except property without writing language path.

Resources