Search code examples
phplaravelpostmancrudendpoint

Put Route returns CSRF token mismatch Laravel


I am trying to configure a crud api for a blog and right now i made the PostController like this:

<?php

namespace App\Http\Controllers;

use App\Models\Post;
use App\Http\Requests\StorePostRequest;
use Illuminate\Http\Request;

class PostController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index()
    {
        $posts = Post::all();
        return response()->json([
            'posts' => $posts
        ]);
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(StorePostRequest $request)
    {
        $post = Post::create($request->all());

        return response()->json([
            'message' => "Post Created successfully!",
            'post' => $post
        ], 200);
    }

    /**
     * Display the specified resource.
     */
    public function show(Post $post)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     */
    public function edit(Post $post)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     */
    public function update(StorePostRequest $request, Post $post)
    {
        $post->update($request->all());

        return response()->json([
            'message' => "Post Updated successfully!",
            'post' => $post
        ], 200);
    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroy(Post $post)
    {
        $post->delete();

        return response()->json([
            'status' => true,
            'message' => "Post Deleted successfully!",
        ], 200);
    }
}

and web.php is this one:


<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PostController;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider and all of them will
| be assigned to the "web" middleware group. Make something great!
|
*/

Route::get('/', function () {
    return view('welcome');
});

Route::resource('posts', PostController::class);

and when i try to use postman http://127.0.0.1:8000/posts/ works and shows me all the data but nothing else And yes i switched the GET with POST and even tried with PUT and i get the following:

 "message": "CSRF token mismatch.",

I do not have any front-end in this project to put that csrf field there, how should i solve this?


Solution

  • Api routes should be registered in the routes/api.php file, not in the web.php file. The middleware stack that is applied to the routes in these files is different.

    One of the middlewares that is applied to routes in the web.php file is VerifyCsrfToken, but your requests will never have a csrf-token. Moving your api routes from web.php to api.php will resolve the csrf-token issues.

    From the RouteServiceProvider:

    $this->routes(function () {
        Route::middleware('api') // api is a middleware group
            ->prefix('api')
            ->group(base_path('routes/api.php'));
    
        Route::middleware('web') // web is a middleware group
            ->group(base_path('routes/web.php'));
    });
    

    The middleware groups correspond with these middleware stacks:

    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, // causes the issue
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],
     
        'api' => [ // does not have the csrf middleware
            \Illuminate\Routing\Middleware\ThrottleRequests::class.':api',
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],
    ];