Laravel middleware 'api' MethodNotAllowedHttpException - php

in my /routes/api.php next code
Route::middleware('api')->group(function(){
Route::get('/prepare/', 'CompgenApiController#prepareDefault');
Route::get('/replace/', 'CompgenApiController#replaceImage');
Route::get('/collage/', 'CompgenApiController#collage');
Route::get('/generate/', 'CompgenApiController#generate');
Route::post('/upload/', 'CompgenApiController#userUpload');
});
all get-methods work fine but when i try use Route::post i got an error
"Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException"
this is the request code
uploadFile(){
axios.post('/api/upload/',{
src: 'test'
}).then(function (result) {
console.log(result);
});
}
also in my app/Http/Middleware/VerifyCsrfToken.php i have
protected $except = [
'/api/upload/'
];

what you have done is applied an api middleware on routes. why don't you try to update your code like this and then the routes defined inside your controller will be accepted with an api/ prefix.
Route::group([
'prefix' => 'api',
'middleware' => ['auth.api']
], function () {
//define routes here
});

Related

Laravel apply multiple middlewares on API routes

I have created a custom middleware to check if $request->wantsJson() then it should allow the route to call the function. The order would be
1. Check for JSON
2. Check Auth
How can I implement the middle wares in this order? I have tried the following but its not working
Route::group(['middleware' => ['auth:api', 'json']], function () {
Route::group(['prefix' => 'V1'], function () {
Route::post('logout', 'API\V1\AuthController#logout');
});
});
Did you register the middleware in App\Http\Kernel.php route middleware?
https://laravel.com/docs/master/middleware#assigning-middleware-to-routes
protected $routeMiddleware = [
// ...
'json' => \App\Http\Middleware\CheckForJson::class,
];
There is also an additional array for forcing the priority (order) of non-global middleware.
https://laravel.com/docs/master/middleware#sorting-middleware
protected $middlewarePriority = [
// ...
\App\Http\Middleware\CheckForJson::class,
];

How to Map new route to specific old route in Laravel?

I have following route group for admin panel
Route::prefix('admin')->group(function (){
.
.
.}
I want to wrap this route to a new route e.g asda12asda
so that old behavior :
/admin/users
is changed to :
/asda12asda/users
not allowing old route. I don't want to change it internally from the system and want to find some efficient Laravel way to achieve it.
Redirect the old route to a new route
Route::prefix('admin')->group(function (){
Route::any('login', function () {
// Redirect to new route
redirect()->route('new route');
});
});
by creating a new route and mapping it accordingly
Route::prefix('asda12asda')->group(function () {
Route::any('login', function () {
// Do whatever you were about to do
})->name('new route');
});
If you are using Laravel 5.4 then you can add a new route file. Assume your route name is
adsp.php then add it to RouteServiceProvider.php like this.
protected function mapApiRoutes()
{
Route::group([
'middleware' => 'web',
'namespace' => $this->namespace,
], function ($router) {
require base_path('routes/adsp.php.php');
});
}

TokenMismatchException in VerifyCsrfToken.php line 67 using Route::post()

I understand that this is a common issue with Laravel 5.x, but my particular run-in with the problem is not through submitting a form.
Instead, I am using postman to send data to a URL endpoint to test if data is successfully received. I'm working with Laravel 5.2 and I'm very much new to it!
Here is my routes.php file (related content)
Route::group(['middleware' => 'web'], function () {
Route::post('/cart', 'CartController#buildcart');
});
Here is my CartController.php (entire file)
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
class CartController extends Controller
{
public function buildcart(){
echo 'hello';
}
}
As simple as that is, when I use postman to send random data to the /cart URL, I get
TokenMismatchException in VerifyCsrfToken.php line 67:
Can anyone help me understand why this is failing? I don't see how using
{{ csrf_token() }}
is the solution for this case since the data is coming from an external source.
Running list of things I've tried
Removing the route from Route::group(['middleware' => 'web'], function () {
using Route::group(array('before' => 'csrf', ['middleware' => 'web']), function () {
try add the route to this route group
Route::group(array('before' => 'csrf', ['middleware' => 'web']), function () {
Route::post('/cart', 'CartController#buildcart');
});
EDIT : try to comment this line in app\kernel.php
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
// \App\Http\Middleware\VerifyCsrfToken::class,
],
'api' => [
'throttle:60,1',
],
];
Try changing the middleware in the routes.php file. I think, you are getting the error as you are not authorized to use the route. Try this:
Route::group(['middleware' => 'guest'], function () {
Route::post('/cart', 'CartController#buildcart');
});

Laravel 5.2 Session flash not working even with web middleware

I am trying to implement flash messaging using sessions but am unable to do so.
In my controller I have:
public function store(Request $request) {
session()->flash('donald', 'duck');
session()->put('mickey', 'mouse');
return redirect()->action('CustomerController#index')->with('bugs', 'bunny');
}
But when I check the session variables in the view, I can only see the values from session()->put('mickey', 'mouse').
Session:
{"_token":"F6DoffOFb17B36eEJQruxvPe0ra1CbyJiaooDn3F","_previous":{"url":"http:\/\/localhost\/customers\/create"},"flash":{"old":[],"new":[]},"mickey":"mouse"}
A lot of people encountered this problem by not having the relevant routes inside the web middleware. I made sure to do this as well but it still wouldn't work.
In routes.php:
Route::group(['middleware' => ['web']], function () {
Route::get('/', function () {
return view('welcome');
});
Route::get('/customers', 'CustomerController#index');
Route::get('/customers/create', 'CustomerController#create');
Route::post('/customers', 'CustomerController#store');
});
In Kernel.php:
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
],
'api' => [
'throttle:60,1',
],
];
Can anyone let me know what I could be doing wrong here? Thanks!
Fixed the issue by replacing
Route::group(['middleware' => ['web']], function () {
...
});
with
Route::group(['middlewareGroups' => ['web']], function () {
...
});
No idea why this works though when all the documentation suggests that we use ['middleware' => ['web']]
This is more than likely because of a change that was made to the Laravel framework (v5.2.27) that all routes by default are part of the "web" middleware, so assigning it again in your routes.php file ends up assigning it twice.
The solution is either to remove the "web" middleware from your routes OR remove the automatic assignment from the RouteServiceProvider.
Before the Laravel update:
// RouteServiceProvider.php
$router->group(['namespace' => $this->namespace], function ($router) {
require app_path('Http/routes.php');
});
After the Laravel update:
// RouteServiceProvider.php
$router->group([
'namespace' => $this->namespace, 'middleware' => 'web',
], function ($router) {
require app_path('Http/routes.php');
});
Notice how the new update automatically applies the "web" middleware to all routes. Simply remove it here if you wish to continue using Laravel 5.2 as you have before (manually assigning "web" middleware in your routes.php).
Build your Session flash info by using this code:
<?php
Session::flash("Donald", "Duck")
// Or in your code style.
$request->session()->flash("Donald", "Duck")
?>
Check it in your view with:
#if(Session::has("Donald")
{{Session::get("Donald")}}
#endif
You forget to use $request :)
In Controller:
use Session,Redirect;
public function store(Request $request)
{
Session::flash('donald', 'duck');
Session::put('mickey', 'mouse');
return Redirect::to('/customers')->with('bugs', 'bunny');
}
In 'view' check the data is getting or not:
<?php
print_r($bugs);die;
?>
Good Luck :)
I use the following:
In my controller:
public function xyz(){
// code
// This
return redirect()->action('homeController#index')->with('success', 'Check! Everything done!');
// Or this
return redirect('/index')->with('success', 'Check! Everything done!');
}
In my view:
#if(session('success'))
{{ session('success') }}
#endif
Nothing else. The web-middleware is assigned to every route.
I dont know why but on Windows you need changes in your routes: middleware to middlewareGroups, like that:
So, in your app\Kernel.php, you need put the StartSession at first on array of middleware group web:

method post, put, delete route not work on laravel 5

I try test api rest on laravel 5 but I have problems with method post, put, delete.
In my route.php file I have code:
Route::group(['prefix' => 'api'], function()
{
Route::group(['prefix' => 'user'], function()
{
Route::get('', ['uses' => 'UserController#allUsers']);
Route::get('{id}', ['uses' => 'UserController#getUser']);
Route::post('', ['uses' => 'UserController#saveUser']);
Route::put('{id}', ['uses' => 'UsercCntroller#updateUser']);
Route::delete('{id}', ['uses' => 'UserController#deleteUsers']);
});
});
Route::get('/', function()
{
return 'Enjoy the test...';
});
and in UserController.php have code:
public function allUsers()
{
return 'test';
}
public function getUser($id)
{
return 'test get user';
}
public function saveUser()
{
return 'test save user';
}
public function updateUser($id)
{
return 'test update user';
}
public function deleteUsers($id)
{
return 'test delete user';
}
When I run with method get it works good but with method post, put and delete it does not work.
Why is this?
If you want to make REST APIs then use laravel's generators.
Use php artisan make:controller UserController
Laravel automatically creates RESTful controller class for you with all required methods.
Then just put one line in your routes.php
Route::group(['prefix' => 'api'], function()
{
Route:resource('user', 'UserController');
});
And that's it, now you can access get, post, put, and delete requests very easily.
If you want to see what route I should use for what method then simply fire php artisan route:list from commandline.
And because of laravel comes with built in csrf token verification middleware, you must have to pass _token with your post data request. Or either you can access those routes without csrf token verification by doing this:
Go to kernel.php in Http folder under the app directory, and comment the csrfToken line.
protected $middleware = [
'Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode',
'Illuminate\Cookie\Middleware\EncryptCookies',
'Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse',
'Illuminate\Session\Middleware\StartSession',
'Illuminate\View\Middleware\ShareErrorsFromSession',
// 'App\Http\Middleware\VerifyCsrfToken',
];

Categories