Greetings StackOverflowers,
I'm experiencing a problem with CSRF token verification on Laravel 5.5/Spark 5.0.0.
The problem only occurs if I'm making a request to any route in the /api group that is not a GET request (I.E. POST, DELETE etc.).
But basically, the request fails with the error 419 (unknown status). Although not the most helpful error message, I narrowed it down to CSRF tokens verification failure.
When I add /api/* into the exclusion list in /app/Http/Middleware/VerifyCsrfToken.php, the request to /api/test works fine and I get a 200 response code.
Any other POST requests to any other route not under the /api group work and authenticate fine.
Relevant Files
Here are the files which I feel may be relevant. If more information/code is required, please ask.
routes/api.php
<?php
Route::group([
'middleware' => 'auth:api'
], function () {
Route::post('/test', 'Api\DocumentController@test');
});
Note: I did try removing the 'auth' middleware from this controller, too. It's presence has no bearing on this problem
app/Http/Controllers/Api/DocumentController.php
<?php
namespace App\Http\Controllers\Api;
use App\Document;
use App\Http\Controllers\Controller;
class DocumentController extends Controller
{
public function __construct() {
$this->middleware('auth');
}
public function test() {
return ['test' => true];
}
}
app/Http/Kernel.php
<?php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* @var array
*/
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
];
/**
* The application's route middleware groups.
*
* @var array
*/
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,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\Laravel\Spark\Http\Middleware\CreateFreshApiToken::class,
],
'api' => [
//'throttle:60,1',
'bindings',
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\App\Http\Middleware\VerifyCsrfToken::class
],
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* @var array
*/
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'dev' => \Laravel\Spark\Http\Middleware\VerifyUserIsDeveloper::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'hasTeam' => \Laravel\Spark\Http\Middleware\VerifyUserHasTeam::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'subscribed' => \Laravel\Spark\Http\Middleware\VerifyUserIsSubscribed::class,
'teamSubscribed' => \Laravel\Spark\Http\Middleware\VerifyTeamIsSubscribed::class,
];
}
Note: even though axios.defaults.headers.common['X-CSRF-TOKEN'] is set to the value ofSpark.csrfToken`, I added that meta tag below anyway, just in case.
resources/views/vendor/spark/layouts/app.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
...
<meta name="csrf-token" content="">
...
axios.defaults.headers.common value
{"X-Requested-With":"XMLHttpRequest","X-CSRF-TOKEN":"rEhGfZhMW5eGdI2EffF0g5kgYUwUItrjfUIDx73n"}
SparkServiceProvider.php
<?php
namespace App\Providers;
use Laravel\Spark\Spark;
use Laravel\Spark\Providers\AppServiceProvider as ServiceProvider;
class SparkServiceProvider extends ServiceProvider
{
/**
* Your application and company details.
*
* @var array
*/
protected $details = [
'vendor' => 'Your Company',
'product' => 'Your Product',
'street' => 'PO Box 111',
'location' => 'Your Town, NY 12345',
'phone' => '555-555-5555',
];
/**
* The address where customer support e-mails should be sent.
*
* @var string
*/
protected $sendSupportEmailsTo = null;
/**
* All of the application developer e-mail addresses.
*
* @var array
*/
protected $developers = [
'test@test.test'
];
/**
* Indicates if the application will expose an API.
*
* @var bool
*/
protected $usesApi = true;
/**
* Finish configuring Spark for the application.
*
* @return void
*/
public function booted()
{
Spark::useStripe()->noCardUpFront()->trialDays(10);
Spark::useRoles([
'regional-manager' => 'Regional Manager',
'team-manager' => 'Team Manager',
'team-member' => 'Team Member'
]);
}
}
AJAX Request Info
I have checked, double checked and triple checked that the required cookies and headers are being sent upon each request.
I also compared the raw request data for the working request and non-working requests and determined that they are in exactly the same format. I observed in each of the requests that do work, that the X-XSRF-TOKEN header, the XSRF-TOKEN cookie and the spark_token cookie changes on each request. But the X-CSRF-TOKEN header does not, until the session changes.
Working Request
POST /spark/kiosk/announcements HTTP/1.1
Host: hilton-project.local
Connection: keep-alive
Content-Length: 98
Pragma: no-cache
Cache-Control: no-cache
Origin: http://ift.tt/2xQRcW8
X-XSRF-TOKEN: eyJpdiI6ImJQVEpIYkZGNFR6dlIrVURJTjlWbHc9PSIsInZhbHVlIjoiY1pmTUxzNlo4TW9cL2JIXC9NVTd6NE5lQjBDXC9jeXVoM1JmZFh5OHlKeUFQVTFGZHVVZ3VTMlhaajBPWGErdlcrem9CM3llYTNjMmoyQ01TYW1YXC9YQTBBPT0iLCJtYWMiOiJiOTFjMGNlN2RkZjAwNWQyZWM3YzZiZTJhMGMxNTI1YzljMjdjZDcxOGRiOWVhNjIzNWE0ODJjOTc4NzY2MDg4In0=
X-CSRF-TOKEN: rEhGfZhMW5eGdI2EffF0g5kgYUwUItrjfUIDx73n
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36
Content-Type: application/json;charset=UTF-8
X-Requested-With: XMLHttpRequest
Accept: */*
Referer: http://ift.tt/2yWfvQj
Accept-Encoding: gzip, deflate
Accept-Language: en-GB,en;q=0.8
Cookie: __stripe_mid=f959cec8-c6d6-41d6-a682-d864215cda32; remember_web_59ba36addc2b2f9401580f014c7f58ea4e30989d=eyJpdiI6IkZBbjVid0VQd3dzZDJraGY4OEZyNmc9PSIsInZhbHVlIjoic1NkSzdDMVNQT0ErY3lYcndsQlJzb2JueENlYmhlb3BLVWd1NUg4ZmgwXC94UEd1eWdQZTIwVWdxXC9sVGJUVkZjMjFrZGs2QjI2VVdxaDg5OUM0VCtkU3N1Tm5NR0RnRVdZVzZ3akdhOEJKNzZsYTczNDVFclVZVHE2cG1oMDh3UjBOdXVlTVlGb2gwYURWK2YzUHNNa1dxRGJqWGRlVE01NDlnNkM5Ujl6RUwwNTV3a1M5RGdaaFZPU05RN2RPSUYiLCJtYWMiOiJiZjIyMWUwOWE4YWIyNzY2ZjQ4MTI2NTI1ZmZlODJjNjBlZmI2NzEyOTFmYWZiZWMzMTY4N2NkYWViM2YyZTgxIn0%3D; spark_token=eyJpdiI6IlZpdTFJazB0ek50ejNJK3U5VnlnYVE9PSIsInZhbHVlIjoieXpaK1JHT2k5UjZ6XC9vcFRsc0NMS2tLWWFIUSt2XC91MzY1TXdTNHBOUjJtWE1hSlViOHMrdDROMzIya3pIbGNhdTlwanhOeUxDTVJVUUFwbXBZVFZUTHJndjVxRFVORURhNWkzbmR6UHpjcDJycVBWc2NvcHpSbHBjQzJ1TVNxclRoNE80Q2NUaXNuN0JOM1k5ajlqWmVIK2hDWUxVTmdrbzVSYlBkWjJSbmhzUnVnK3JxOHlXbGExZ3hIWm5cL041eHo5WDlBRE8ydVdEUEhIdkk0dkJ6NVorWERhekZQS2kzWkx2TXA2NVFZakhKQ3pnemZ5eTZwR3prdk12eXVYeldRM1VrZGErRVhFdWp4NjcrcXpPWFE9PSIsIm1hYyI6IjlmYzg2YTAzYzFiNThmOWE2ZTM0OTU5MDY1NWFhMDUxYjBlOGRjNzEyNDRjNTlmMjNiYTQwYzY4MzViNjY0MDAifQ%3D%3D; XSRF-TOKEN=eyJpdiI6ImJQVEpIYkZGNFR6dlIrVURJTjlWbHc9PSIsInZhbHVlIjoiY1pmTUxzNlo4TW9cL2JIXC9NVTd6NE5lQjBDXC9jeXVoM1JmZFh5OHlKeUFQVTFGZHVVZ3VTMlhaajBPWGErdlcrem9CM3llYTNjMmoyQ01TYW1YXC9YQTBBPT0iLCJtYWMiOiJiOTFjMGNlN2RkZjAwNWQyZWM3YzZiZTJhMGMxNTI1YzljMjdjZDcxOGRiOWVhNjIzNWE0ODJjOTc4NzY2MDg4In0%3D; laravel_session=eyJpdiI6Ik15REplTW9cL2U4dERDUjBMVjRxdVwvZz09IiwidmFsdWUiOiJxaFZ1YXVPaDk2bTcxYTcyakkrT3lMMFJYUjVIdFhhRnRIZGlQUitFQk8zRDI1QkZTRXQwZm92blIwSDVRazZvZnY0ajdlclJBQUx0RlpZOVpnT1dpQT09IiwibWFjIjoiZGRkNzQ2ZjU5ODRjMmU0ZmE0MjMzMGNkYmRkNTMxMTFhYjIxOGFlYTgyNTg4MDZhYjFmZWMwNjkwNTU3ZDEzYSJ9
Non-Working Request
POST /api/test HTTP/1.1
Host: hilton-project.local
Connection: keep-alive
Content-Length: 10
Pragma: no-cache
Cache-Control: no-cache
Origin: http://ift.tt/2xQRcW8
X-XSRF-TOKEN: eyJpdiI6IkY0eXhIY1psQ1RYd25pNVpBUkt0ZkE9PSIsInZhbHVlIjoiU1E0anplUXZZSlZtMFVmQnpFd3RablNEV0tOSFZKcjVJQm1kME00M0I2VXV2cXQwTHc5NG1tclRHYnVzbFlZQktjeDR2Y1dscUlxNmwxUUpOMzN1Tnc9PSIsIm1hYyI6ImJmYTdhZjE5M2Y5NDdmNTBlMDgyY2Q1YzVmNjlmZDljMjA2Nzc0NGY2NjI2NmNiYThhZWU5ZDk2MWZlZTQyNWYifQ==
X-CSRF-TOKEN: rEhGfZhMW5eGdI2EffF0g5kgYUwUItrjfUIDx73n
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36
Content-Type: application/json;charset=UTF-8
X-Requested-With: XMLHttpRequest
Accept: */*
Referer: http://ift.tt/2yWfvQj
Accept-Encoding: gzip, deflate
Accept-Language: en-GB,en;q=0.8
Cookie: __stripe_mid=f959cec8-c6d6-41d6-a682-d864215cda32; remember_web_59ba36addc2b2f9401580f014c7f58ea4e30989d=eyJpdiI6IkZBbjVid0VQd3dzZDJraGY4OEZyNmc9PSIsInZhbHVlIjoic1NkSzdDMVNQT0ErY3lYcndsQlJzb2JueENlYmhlb3BLVWd1NUg4ZmgwXC94UEd1eWdQZTIwVWdxXC9sVGJUVkZjMjFrZGs2QjI2VVdxaDg5OUM0VCtkU3N1Tm5NR0RnRVdZVzZ3akdhOEJKNzZsYTczNDVFclVZVHE2cG1oMDh3UjBOdXVlTVlGb2gwYURWK2YzUHNNa1dxRGJqWGRlVE01NDlnNkM5Ujl6RUwwNTV3a1M5RGdaaFZPU05RN2RPSUYiLCJtYWMiOiJiZjIyMWUwOWE4YWIyNzY2ZjQ4MTI2NTI1ZmZlODJjNjBlZmI2NzEyOTFmYWZiZWMzMTY4N2NkYWViM2YyZTgxIn0%3D; spark_token=eyJpdiI6IlZpdTFJazB0ek50ejNJK3U5VnlnYVE9PSIsInZhbHVlIjoieXpaK1JHT2k5UjZ6XC9vcFRsc0NMS2tLWWFIUSt2XC91MzY1TXdTNHBOUjJtWE1hSlViOHMrdDROMzIya3pIbGNhdTlwanhOeUxDTVJVUUFwbXBZVFZUTHJndjVxRFVORURhNWkzbmR6UHpjcDJycVBWc2NvcHpSbHBjQzJ1TVNxclRoNE80Q2NUaXNuN0JOM1k5ajlqWmVIK2hDWUxVTmdrbzVSYlBkWjJSbmhzUnVnK3JxOHlXbGExZ3hIWm5cL041eHo5WDlBRE8ydVdEUEhIdkk0dkJ6NVorWERhekZQS2kzWkx2TXA2NVFZakhKQ3pnemZ5eTZwR3prdk12eXVYeldRM1VrZGErRVhFdWp4NjcrcXpPWFE9PSIsIm1hYyI6IjlmYzg2YTAzYzFiNThmOWE2ZTM0OTU5MDY1NWFhMDUxYjBlOGRjNzEyNDRjNTlmMjNiYTQwYzY4MzViNjY0MDAifQ%3D%3D; XSRF-TOKEN=eyJpdiI6IkY0eXhIY1psQ1RYd25pNVpBUkt0ZkE9PSIsInZhbHVlIjoiU1E0anplUXZZSlZtMFVmQnpFd3RablNEV0tOSFZKcjVJQm1kME00M0I2VXV2cXQwTHc5NG1tclRHYnVzbFlZQktjeDR2Y1dscUlxNmwxUUpOMzN1Tnc9PSIsIm1hYyI6ImJmYTdhZjE5M2Y5NDdmNTBlMDgyY2Q1YzVmNjlmZDljMjA2Nzc0NGY2NjI2NmNiYThhZWU5ZDk2MWZlZTQyNWYifQ%3D%3D; laravel_session=eyJpdiI6IjVjV1BHRnh5T29lN0lPSWpIdnRxSEE9PSIsInZhbHVlIjoid3YyQXV5Sk45TlZYYm9xODhTN0ZnWGNDMjB3am9KT0VmZjFnTDNLNm1wdkhIQzl5UW9wcndWNytsSGNvb1FBeUJxS0t2UU03QXZBMVpVOTFOc1I2c3c9PSIsIm1hYyI6IjdiNzMyOWI0NDVhM2Y5MDc2NTdiNGU0NDEzN2Q2ZmQ1NDg2YWZlY2VmZWI2ZGNmNmIwODFiM2IxZWRkZjE5MjUifQ%3D%3D
More Information
When I spawn a new Spark installation using spark new project-name, all requests to /api work fine.
I have sat and gone through pretty much every relevant file I can find, and I can't find a difference in any potentially related file that seems like it would have a bearing.
I'd rather not start afresh and move everything over, as I also have a Spark skin installed, and that was a bit painful to get working.
I have also considered the possibility that perhaps the Spark skin was to blame for the malfunctioning. However, I have gone through every file that the Spark skin actually changes (all PHP and even JS files), and I can find nothing that even touches CSRF token verification.
The author of the skin boasts compatibility with the latest versions of Laravel/Spark, and it's quite a popular skin on ThemeForest, so I can't imagine it is to blame, and seeing as I checked every file, I think we can rule it out.
I have also trawled through countless questions and "solutions" to this problem. But results are flooded with questions where the answer was as simple as they hadn't included the CSRF token in the request, which I definitely am.
Environment
- Homestead/Vagrant/VirtualBox setup on Windows 10 x64
- PHP 7.1.9 on Ubuntu 16.04.1
Any insight into the potential cause would be greatly appreciated.
via Chebli Mohamed
Aucun commentaire:
Enregistrer un commentaire