Skip to content

Instantly share code, notes, and snippets.

@tao
Last active September 11, 2023 14:29
Show Gist options
  • Star 23 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save tao/fba880299bdfdcfd491582724ede9dd7 to your computer and use it in GitHub Desktop.
Save tao/fba880299bdfdcfd491582724ede9dd7 to your computer and use it in GitHub Desktop.
Using Passport with Laravel Spark
# Installation
As far as I know this is how to get Passport on Laravel Spark working correctly, it works so far for me over the API but there might be something I am still missing.
I am using the following software versions in composer.json:
```
"require": {
"php": ">=5.6.4",
"laravel/framework": "5.3.*",
"laravel/spark": "~2.0",
"laravel/cashier": "~7.0",
"laravel/passport": "^1.0"
},
```
To get started, install Passport via the Composer package manager:
```
composer require laravel/passport
```
Next, register the Passport service provider in the providers array of your config/app.php configuration file:
```
Laravel\Passport\PassportServiceProvider::class,
```
The Passport service provider registers its own database migration directory with the framework, so you should migrate your database after registering the provider. The Passport migrations will create the tables your application needs to store clients and access tokens:
```
php artisan migrate
```
Next, you should run the `passport:install` command. This command will create the encryption keys needed to generate secure access tokens. In addition, the command will create "personal access" and "password grant" clients which will be used to generate access tokens:
```
php artisan passport:install
```
After running this command, add the `Laravel\Passport\HasApiTokens` trait to your App\User model. This trait will provide a few helper methods to your model which allow you to inspect the authenticated user's token and scopes:
The SparkUser model already has `HasApiTokens` trait however you need to include the Passport\HasApiTokens trait in the App\User model so you are able to create API tokens in the spark user interface.
```
<?php
namespace App;
use Laravel\Passport\HasApiTokens;
use Laravel\Spark\CanJoinTeams;
use Laravel\Spark\User as SparkUser;
class User extends SparkUser
{
use CanJoinTeams, HasApiTokens;
```
Next, you should call the `Passport::routes` method within the boot method of your AuthServiceProvider. This method will register the routes necessary to issue access tokens and revoke access tokens, clients, and personal access tokens:
```
<?php
namespace App\Providers;
use Carbon\Carbon;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Laravel\Passport\Passport;
class AuthServiceProvider extends ServiceProvider
{
...
public function boot()
{
$this->registerPolicies();
Passport::routes();
Passport::pruneRevokedTokens();
Passport::tokensExpireIn(Carbon::now()->addDays(15));
Passport::refreshTokensExpireIn(Carbon::now()->addDays(30));
}
```
Finally, in your config/auth.php configuration file, you should set the driver option of the api authentication guard to passport. This will instruct your application to use Passport's TokenGuard when authenticating incoming API requests:
```
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
// 'driver' => 'spark',
'driver' => 'passport',
'provider' => 'users',
],
],
```
You can go ahead and follow the documentation to add the vue components to the Spark admin section now, just publish the views, add them to the templates and run gulp again.
You might have to add `"laravel-elixir-vue": "^0.1.4",` to pacakge.json then add `require('laravel-elixir-vue');` to your gulpfile.js in order for gulp to run correctly, double check that you have at least "vue-resource": "~1.0.1" as well in package.json.
I added these to the Kiosk section so only the developers can access the OAuth widgets, if each team in Spark needs access to them then I assume you would add them to the team settings page.
# Testing
Add this to routes/api.php:
```
Route::group([
'middleware' => 'auth:api'
], function () {
Route::get('users', function() {
return['username' => 'tao'];
});
});
Route::get('create-test-token', function() {
$user = \App\User::find(1);
// Creating a token without scopes...
$token = $user->createToken('Test Token Name')->accessToken;
return ['token' => $token];
});
```
You can now either create an api token from the Spark UI, or api/create-test-token or call the method below, you will find a similar access_token returned each time:
*The client_id and secret I am using here is from the database record with the name "Sendtao Password Grant Client" with `password_client:true` after running `php artisan passport:install`.
```
POST /oauth/token HTTP/1.1
Content-Type: application/json
Host: spark.valet
Connection: close
User-Agent: Paw/3.0.12 (Macintosh; OS X/10.12.0) GCDHTTPRequest
{
"grant_type":"password",
"client_id":2,
"client_secret":"88738...aid6bhU",
"scope":"*",
"username": "my-email@company.com",
"password": "my-secret"
}
```
You can test the api by confirming you can reach the api/users with the `Authorization: Bearer ...` header:
```
GET /api/users HTTP/1.1
Accept: application/json
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6IjJhNTM0OGMyMTljMGUwYzEzMTE3NTVkNTJkMjdkMTY3NjFiMDQ2MTVmZDA4YzE5M2NhYzVkNjc1NDFmYzk5OTZjNjU4YmE4ZGFlZjNkOTAzIn0.eyJhdWQiOiIxIiwianRpIjoiMmE1MzQ4YzIxOWMwZTBjMTMxMTc1NWQ1MmQyN2QxNjc2MWIwNDYxNWZkMDhjMTkzY2FjNWQ2NzU0MWZjOTk5NmM2NThiYThkYWVmM2Q5MDMiLCJpYXQiOjE0NzYyMTQ1ODMsIm5iZiI6MTQ3NjIxNDU4MywiZXhwIjo0NjMxODg4MTgzLCJzdWIiOiIxIiwic2NvcGVzIjpbXX0.tXOkrnsEvKQ0r5d8Xh9jvxGN8KaRbyOIB536fdq5kxKGlYLesT2hy5WadO__3X8OWIyiygltLb2-j9pWAI_ZjWuUePh-9LpSn_Nup9mxuTQ3oavWsGEVy4b0eqSG7ASgw66caXOL883WlSFhsVqYCLxbakMz7LT-Ug_PVQb3GS1_-7FP_2QdhKebyG6Xgcn5g6H8oWKdsvs778-gDNqJTK4vBf1Kf_ywo4-Cs5z2N9SysO2tLtnOC3CHzhnGMrWIzDm5i-qc9opdIKy1nyWO1M7oNSrHngqtSJxIdb28_s8Oqx-kZ5hxr76GJMjrgOrT19HQD3sShnlEougxD6WqEdyeaJeiTsxUz8nPW3Mo5DVp3KdYhpphEzwY_aaiH49VxE1UwQ1HJQq_Zm8skoH-d8g0QPMdhwBgXhl0I8X40i235JEC72EyGvFADSYUEM5dGhICChHRSHm0cIMxum_xWKz1fNbDS7GUyaF3vlwCuaFQ8jzxEq974pNH6f4PLEFc1b9dR335gOM-x6cawIZQVr91CickUsyCFJ4w_Mva7XSP62klvgapiC7VhbAbNU4kq3UG0vNG-LCrZ7QVqJcaKw3GcXHMR91ddRisJ5-g7HgLxMBQzZikTqkpPKujU9P3Jq-y15Kh9xKaPVuLz-n7VuhmZmvuPRhrLk3UpYymezM
Host: sendtao--spark.valet
Connection: close
User-Agent: Paw/3.0.12 (Macintosh; OS X/10.12.0) GCDHTTPRequest
```
And if everything workout out you should get the correct response:
```
{
"username": "tao"
}
```
# Refresh Token
```
POST /oauth/token HTTP/1.1
Content-Type: application/json
Host: spark.valet
Connection: close
User-Agent: Paw/3.0.12 (Macintosh; OS X/10.12.0) GCDHTTPRequest
Content-Length: 839
{
"grant_type": "refresh_token",
"refresh_token": "aFc+d5Ola6xdFlOHQ...your...refresh...token...NnEwuylw=",
"client_id": 2,
"client_secret": "88738X...id6bhU",
"scope": "*"
}
```
@echol
Copy link

echol commented Sep 20, 2018

Dude you literally saved me hours of work! This was the only real solution to my problem.
I kept using Laravel/Spark/HasApiTokens instead of Laravel/Passport/HasApiTokens and I didn't update:
'api' => [ // 'driver' => 'spark', 'driver' => 'passport', 'provider' => 'users' ]

@tomyates
Copy link

tomyates commented Oct 2, 2019

This is brilliant. Helped me massively.

@tao
Copy link
Author

tao commented Oct 2, 2019

Great, glad it's still helpful. I haven't updated the code in years but it's still running smoothly for us.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment