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)
}
}
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.
Related Questions
- → How to update data attribute on Ajax complete
- → October CMS - Radio Button Ajax Click Twice in a Row Causes Content to disappear
- → Octobercms Component Unique id (Twig & Javascript)
- → Passing a JS var from AJAX response to Twig
- → Laravel {!! Form::open() !!} doesn't work within AngularJS
- → DropzoneJS & Laravel - Output form validation errors
- → Import statement and Babel
- → Uncaught TypeError: Cannot read property '__SECRET_DOM_DO_NOT_USE_OR_YOU_WILL_BE_FIRED' of undefined
- → React-router: Passing props to children
- → ListView.DataSource looping data for React Native
- → Can't test submit handler in React component
- → React + Flux - How to avoid global variable
- → Webpack, React & Babel, not rendering DOM