Fixing “Syntax error or access violation: 1071 Specified key was too long;” Courtesy of Laravel News

I found this fix on Laravel News, if you haven’t been there… leave this site and go there now, and just wanted to record it in a way that was easy for me to access. I’ve Googled this thing 3 times this week.

<?php use Illuminate\Support\Facades\Schema; public function boot() { Schema::defaultStringLength(191); }
AppServiceProvider.php

How to use Client Credentials Grant Tokens for your API authorization with Laravel 5.4’s Passport

In trying to build a very small micro-service I decided to use client credential grant tokens. I didn’t need users or personal tokens. I just needed one of my other sites to be able to access data for this new micro-service.

According to Taylor, “The client credentials grant is suitable for machine-to-machine authentication” which sounds just great. So I set off to build the entire service using TDD with Passport::actingAs() to mimic authorization knowing I’d do a final external test once it all was working.

All is working great and my tests are passing with my testing database. So, I run migrations on my real database, create my passport client with “php artisan passport:client,” give it a user id of 1, “ApiAccess” for the name for funsies, and keep the default for the redirect. This gives me a Client ID and Client secret.

I head over to Postman, pop those in, send a post and get my access token.

So far, so good. Now, I grab the access token, throw it in my headers, and fire off a post to my api waiting to be stunned by my own greatness…

{"error":"Unauthenticated."}

Well shit.

After a 2ish hours, I figured out how to implement it without making a mess. These instructions assume you know what Client Credential Grant Tokens are for (read the above link about “machine-to-machine”) and why you might use them. Also it doesn’t address a funky token expiration issue that some found in postman. This, it turned out, didn’t affect me but did lead me on a wild goose chase for a bit.

To start with, move all your API routes that you want to use client credential authorization on out of:

/routes/api.php

and move them into a new route file titled:

/routes/client_credentials.php

This will allow us to separate these routes so we don’t affect any other necessary API routing in the future.

Next, we need to begin using this new routes file. To do this, I updated:

/app/Providers/RouteServiceProvider.php

by adding a new method and calling it in the existing “map” method. I’ve abbreviated the file to show only the necessary updates:

<?php class RouteServiceProvider extends ServiceProvider { // existing map method public function map() { $this->mapApiRoutes(); $this->mapWebRoutes(); // ref new method for adding client credentials $this->mapClientCredentialRoutes(); } // new client credentials method protected function mapClientCredentialRoutes() { Route::prefix('api') // I still want /api/ urls ->middleware('client_credentials') // new middleware I'll set up in a bit ->namespace($this->namespace) ->group(base_path('routes/client_credentials.php')); // referencing my new routes file } }
RouteServiceProvider.php

Now that our routes are setup, we need to get that middleware working. We’re going to add it into the same file where the rest of our middleware is defined:

/app/Http/Kernel.php

Here I created a new middleware group for client_credentials (“client_credentials” is the string we used in RouteServiceProvider.php for our new middleware). This file has been abbreviated to show only the updated info.

<?php class Kernel extends HttpKernel { 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, ], 'api' => [ 'throttle:60,1', 'bindings', ], // my new middleware group 'client_credentials' => [ \Laravel\Passport\Http\Middleware\CheckClientCredentials::class, 'throttle:60,1', 'bindings', ] ]; }
Kernel.php

Here you’ll notice we reference:
\Laravel\Passport\Http\Middleware\CheckClientCredentials::class,

That is the %$%$@ middleware to check the client credentials that is no where to be found in the documentation.

With all that in place, I thought, yeah, this isn’t going to work but I’ll try it anyway. I fire up postman, try to hit an endpoint…

It worked! Yay! Hopefully if you’re banging your head against a keyboard right now trying to figure this out, like I was, this article will help.


I pulled ideas from this posts but the implementation was a bit awkward.

How to send POST data with nategood Httpful Package

The Httpful package is fantastic. Searching around I couldn’t find out how to use Httpful\Request::post to send post data to a endpoint. Here’s what I figured out:

<?php $response = Httpful\Request::post($url) ->body(['foo' => 'bar'], Httpful\Mime::FORM) ->send();
sample.php

One the receiving end, you’ll be able to access your info from $_POST. If you found this, you were probably fruitlessly searching the web for the answer just like me. I hope this helps.