Disable Laravel CSRF Protection for /api routes when consuming API with JavaScript

I have a Laravel backend, and React frontend. For development, React runs on localhost:3000 and Laravel on localhost:8080, so I had to allow Cors.

I have set up Passport successfuly and am able to Consume my API with JavaScript.

But on every request, I have to include the X-CSRF-TOKEN to access protected API routes, which works, but for development I'd like to disable CSRF-Protection for the API.

I already tried to add the /api route to the except array in VerifyCsrfToken and removed the middleware from Kernel.php but this doesn't seem to change the fact that I still need to send the CSRF-Token.

I'm using Laravel 5.8 and use JavaScript fetch to make requests.

VerifyCsrfToken:

protected $except = [
    '/api/*'
];```

I commented out VerifyCsrfToken in the Kernel:

protected $middlewareGroups = [
    'web' => [
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        \Illuminate\Session\Middleware\StartSession::class,
        // \Illuminate\Session\Middleware\AuthenticateSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        // \App\Http\Middleware\VerifyCsrfToken::class,
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
        \Laravel\Passport\Http\Middleware\CreateFreshApiToken::class,
    ],

    'api' => [
        'throttle:60,1',
        'bindings',
    ],
];

Example API route:

Route::get('test', function() {
    return response()->json(['success' => 'Hello!']);
})->middleware('auth:api');

How I try to access the API:

const checkStatus = (response) => {
    console.log(response);
    if (response.ok) {
        return response;
    } else {
        const error = new Error(response.statusText);
        error.response = response;
        throw error;
    }
}

const parseJSON = res => res.text();

const Fetcher = {
    get: (ressource) => {
        return fetch(CONSTANTS.API_URL + ressource, {
            method: 'GET',
            mode: 'cors',
            headers: {
                'Accept': 'application/json',
                'X-Requested-With': 'XMLHttpRequest',
                //'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content
            },
            credentials: 'include'
        })
            .then(checkStatus)
            .then(parseJSON)
    },
    post: (ressource, data) => {
        return fetch(CONSTANTS.API_URL + ressource, {
            method: 'POST',
            mode: 'cors',
            headers: {
                'Accept': 'application/json',
                'X-Requested-With': 'XMLHttpRequest',
                //'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content
            },
            credentials: 'include',
            body: data
        })
            .then(checkStatus)
            .then(parseJSON)
    }
}

Answers:

Answer

Try to isolate the problem.
Remove auth:api middleware in the route:

Route::get('api/test', function() {
    return response()->json(['success' => 'Hello!']);
});

Note the url is "api/test" and not just "test" cause you defined the $except array like this:

protected $except = [
    '/api/*'
];

Do your call without passing CSRF token.

EDITED

From laravel documentation about auth:api middleware:

Laravel includes an authentication guard that will automatically validate API tokens on incoming requests. You only need to specify the auth:api middleware on any route that requires a valid access token:

it means you have to pass API token to the routes under auth:api middleware, otherwise you get 401 error.

Answer

under routes folder handle your api routes in api.php not in web.php

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.