Passport OAuth authentication
- Custom migration
- Get started quickly with the front end
- Deploy Passport
- Configure
- Token validity period
- Override the default model
- Issue access token
- JSON API
- Password Authorization Token
- Implicit authorization token
- Client Credentials Authorization Token
- Personal Access Token
- Create Personal Access Client
- Manage Personal Access Token
- JSON API
- GET /oauth/scopes
- ##GET /oauth/personal-access-tokens
- POST /oauth/personal-access-tokens ##DELETE /oauth/personal-access-tokens/{token-id}
- Route protection
- Token scope Use JavaScript to access the API
- Event
- Test
Laravel Passport
- Introduction
- Installation
- Configure
- Issue access token
- Password authorization Tag
- Simplified Authorization Token
- Client authorization token
- Personal access token
- Route protection
- Token scope
- Use JavaScript to access the API
- Event
- Test
Introduction
In Laravel, it is very simple to implement login and authorization based on traditional forms, but how to meet the authorization requirements in API scenarios? In API scenarios, user authorization is usually implemented through tokens instead of maintaining session state between requests. Using Passport in your Laravel project makes it easy to implement API authorization and authentication. Passport can provide a complete OAuth2 server implementation for your application in a few minutes. Passport is built on the League OAuth2 server maintained by Andy Millington and Simon Hamp.
{note} This document assumes you are already familiar with OAuth2. If you don't know OAuth2, please familiarize yourself with OAuth2's common terms and features before reading.
Installation
Before you begin, install Passport through the Composer package manager:
composer require laravel/passport
The Passport service provider uses the framework to register its own database migration directory, so after registering the provider, you should run Passport's migration command to automatically create the data table that stores clients and tokens:
php artisan migrate
Next, run the passport:install
command to create the encryption keys needed to generate the secure access token. This command will also create the "Personal Access" client used to generate the access token. Client and "Password Authorization" client:
php artisan passport:install
After executing the above command, please add Laravel\Passport\HasApiTokens
Trait to the App\User
model, this Trait will provide your model with some helper functions for checking the authenticated user's token and usage scope:
<?php namespace App; use Laravel\Passport\HasApiTokens; use Illuminate\Notifications\Notifiable; use Illuminate\Foundation\Auth\User as Authenticatable; class User extends Authenticatable{ use HasApiTokens, Notifiable; }
Next, in the boot
of AuthServiceProvider
The Passport::routes
function is called in the method. This function registers the routes necessary to issue access tokens and revoke access tokens, client and personal access tokens:
<?php namespace App\Providers; use Laravel\Passport\Passport; use Illuminate\Support\Facades\Gate; use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider; class AuthServiceProvider extends ServiceProvider{ /** * 应用程序的策略映射。 * * @var array */ protected $policies = [ 'App\Model' => 'App\Policies\ModelPolicy', ]; /** * 注册任何认证/授权服务。 * * @return void */ public function boot() { $this->registerPolicies(); Passport::routes(); } }
Finally, add the configuration file config/auth.php
The driver
option of the api
of the authorization guard guards
was changed to passport
. This tweak will cause your application to use Passport's TokenGuard
when validating incoming API requests:
'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], 'api' => [ 'driver' => 'passport', 'provider' => 'users', ], ],
Custom Migrations
If you do not plan to use Passport's default migrations, you should call the Passport::ignoreMigrations
method in the register
method of AppServiceProvider
. You can use this command php artisan vendor:publish --tag=passport-migrations
to export the default migrations.
By default, Passport uses the field "user_id" to identify the user. If you want to use a different field to identify the user (for example: uuid), you can modify the default Passport migration file.
Quick Start with the Front End
{note} In order to use Passport’s Vue component, you must use the Vue JavaScript framework. These components also use the Bootstrap CSS framework. However, if you don't plan to use these tools, these components are also valuable for writing your own front-end components.
Passport provides a series of JSON APIs that you can use to allow your users to create client and personal access tokens. However, writing the front-end code that interacts with these APIs can be time-consuming. Therefore, Passport also includes precompiled Vue components that you can use directly or as a reference for your own front-end.
To use Passport's Vue component, use the vendor:publish
Artisan command:
php artisan vendor:publish --tag=passport-components
The published component will be placed in resources/js/components
Under contents. When components are published, you should register them in your resources/js/app.js
file:
Vue.component( 'passport-clients', require('./components/passport/Clients.vue').default); Vue.component( 'passport-authorized-clients', require('./components/passport/AuthorizedClients.vue').default ); Vue.component( 'passport-personal-access-tokens', require('./components/passport/PersonalAccessTokens.vue').default );
{note} Prior to Laravel v5.7.19, in Adding ".default" when registering a component results in a console error. For an explanation of this change, see the Laravel Mix v4.0.0 Release Notes.
After registering the component, make sure to run npm run dev
to Recompile your resources. After you recompile your resources, you can place the components into your app's template to start creating client and personal access tokens:
<passport-clients></passport-clients> <passport-authorized-clients></passport-authorized-clients>< passport-personal-access-tokens></passport-personal-access-tokens>
Deploying Passport
The first time you deploy Passport in your production environment, you probably need to run the passport:keys
command. This command generates the keys that Passport needs to generate access tokens. Generated keys should generally not be placed in version control:
php artisan passport:keys
You can use the Passport::loadKeysFrom
method to customize the loading path of Passport keys:
/** * 注册认证 / 授权服务 * * @return void */ public function boot(){ $this->registerPolicies(); Passport::routes(); Passport::loadKeysFrom('/secret-keys/oauth'); }
Configuration
##Validity period of the tokenBy default, the access token issued by Passport is valid for one year. But if you want to customize the validity period of the access token, you can use thetokensExpireIn and
refreshTokensExpireIn methods. The above two methods also need to be called in the
boot method of
AuthServiceProvider:
/** * 注册认证 / 授权服务 * * @return void */ public function boot(){ $this->registerPolicies(); Passport::routes(); Passport::tokensExpireIn(now()->addDays(15)); Passport::refreshTokensExpireIn(now()->addDays(30)); }Override the default modelYou can freely extend the model used by Passport and overwrite the default model through the
Passport class custom model:
use App\Models\Passport\Client; use App\Models\Passport\AuthCode; use App\Models\Passport\TokenModel; use App\Models\Passport\PersonalAccessClient; /** * 注册认证 / 授权服务 * * @return void */ public function boot(){ $this->registerPolicies(); Passport::routes(); Passport::useClientModel(Client::class); Passport::useTokenModel(TokenModel::class); Passport::useAuthCodeModel(AuthCode::class); Passport::usePersonalAccessClientModel(PersonalAccessClient::class); }
Issue access token
Developers who are familiar with OAuth2 must know that the essential part of OAuth2 is the authorization code. When using an authorization code, the client application will redirect the user to your server, and they will approve or deny the request to the client for an access token.
Manage Client
First, to build the application that needs to interact with the application API, the developer will need Register your application by creating a "client". Generally, this includes providing the name of the user's application and a URL to which the application can redirect after the user approves their authorization request.
The passport:client
Command
The easiest way to create a client is to use the Artisan command passport:client
, You can use this command to create your own client for testing your OAuth2 functionality. When you execute the client
command, Passport will prompt you for information about the client, eventually giving you the client's ID and secret:
php artisan passport:client
Redirect URLs
When there are multiple redirect URL whitelists, you can specify them using comma separation when the passport:client
command prompts for the URL:
http://example.com/callback,http://examplefoo.com/callback
{note} Any URL containing commas must be encoded.
JSON API
Considering that your users cannot use the client command, Passport provides a JSON API that can be used to create "clients". This way you don't have to spend time writing controllers to create, update and delete clients.
However, you still need to develop a front-end interface based on Passport's JSON API to provide your users with a client management panel. Below we will list all APIs used to manage clients. For convenience, we use Axios to demonstrate making HTTP requests to the port.
This JSON API is protected by two middlewares, web
and auth
, so it can only be called from the application and cannot be called from outside.
{tip} If you don’t want to implement the entire client management front-end interface yourself, you can use Quick Start with Front-End to build a fully functional front-end interface in a few minutes.
GET /oauth/clients
This route will return all clients of the authenticated user. The main use is to list all users' clients so they can edit or delete them:
axios.get('/oauth/clients') .then(response => { console.log(response.data); });
POST /oauth/clients
This route is used to create new clients. It requires two parameters: the name of the client name
and the post-authorization callback URL redirect
. After approving or denying the authorization request, the user is redirected to the link provided by the redirect
parameter.
When the client is created, the client's ID and key will be returned. The client can use these two values to request an access token from your authorization service. This route will return a new client instance:
const data = { name: 'Client Name', redirect: 'http://example.com/callback'}; axios.post('/oauth/clients', data) .then(response => { console.log(response.data); }) .catch (response => { // 在response里列出错误详情... });
PUT /oauth/clients/{client-id}
This route is used for Update client information. It requires two parameters: the name of the client name
and the post-authorization callback URL redirect
. The user will redirect
be redirected to this link after approving or denying the authorization request. This route will return the updated client instance:
const data = { name: 'New Client Name', redirect: 'http://example.com/callback'}; axios.put('/oauth/clients/' + clientId, data) .then(response => { console.log(response.data); }) .catch (response => { // 在response里列出错误详情... });
DELETE /oauth/clients/{client-id}
This route uses When deleting the client:
axios.delete('/oauth/clients/' + clientId) .then(response => { // });## when requesting token for authorization RedirectAfter the client is created, the developer uses this client's ID and secret to request an authorization code and access token from the application. First, the user accessing the application sends a redirect request to the
/oauth/authorize route of your application. The example is as follows:
Route::get('/redirect', function () { $query = http_build_query([ 'client_id' => 'client-id', 'redirect_uri' => 'http://example.com/callback', 'response_type' => 'code', 'scope' => '', ]); return redirect('http://your-app.com/oauth/authorize?'.$query); });
{tip} Note that the routeApprove requestWhen receiving an authorization request, Passport will automatically display a template page to the user, allowing the user to approve or deny the authorization request. If the user approves the request, they are redirected back to the/oauth/authorize
has been defined in the
Passport::routesmethod. You don't need to define this route manually.
redirect_uri specified by the accessing application.
redirect_uri must be exactly the same as the
redirect link specified when the client was created.
vendor:publish to publish the Passport view. The published view files are stored in
resources/views/vendor/passport:
php artisan vendor:publish --tag=passport-views
Convert the authorization code into an access token
After the user approves the authorization request, he will be redirected back to the accessed application. The accessing application should then request an access token from your application via a POST
request. The request should include the authorization code issued by the application when the user approves the authorization request. In the following example, we use the Guzzle HTTP library to implement this POST
request:
Route::get('/callback', function (Request $request) { $http = new GuzzleHttp\Client; $response = $http->post('http://your-app.com/oauth/token', [ 'form_params' => [ 'grant_type' => 'authorization_code', 'client_id' => 'client-id', 'client_secret' => 'client-secret', 'redirect_uri' => 'http://example.com/callback', 'code' => $request->code, ], ]); return json_decode((string) $response->getBody(), true); });
routing/oauth/token
The returned JSON response will contain # The ##access_token,
refresh_token and
expires_in properties.
expires_in The attribute contains the expiration date of the access token in seconds.
{tip} Like theRefresh tokenIf your application issues a short-lived access token, the user Will need to refresh their access token via the refresh token provided to them when the access token was issued. In the following example, we use the Guzzle HTTP library to refresh the token:/oauth/authorize
route, the
/oauth/tokenroute is in the
Passport::routesmethod Defined, you don't need to define it manually. By default, this route uses the settings of the "ThrottleRequests" middleware for throttling.
$http = new GuzzleHttp\Client; $response = $http->post('http://your-app.com/oauth/token', [ 'form_params' => [ 'grant_type' => 'refresh_token', 'refresh_token' => 'the-refresh-token', 'client_id' => 'client-id', 'client_secret' => 'client-secret', 'scope' => '', ],]); return json_decode((string) $response->getBody(), true);route
/oauth/token will return a JSON response containing
access_token,
refresh_token and
expires_in properties.
expires_in The attribute contains the expiration time of the access token in seconds.
--password after the
passport:client command Parameters to create a password-authorized client. If you have already run the
passport:install command, you do not need to run this command again:
php artisan passport:client --password
Request a token
Once you create a password-granted client, you can issue a POST
to the /oauth/token
route using the user's email address and password. request to obtain an access token. The route has been registered by the Passport::routes
method, so there is no need to define it manually. If the request is successful, you will receive an access_token
and refresh_token
in the JSON response returned by the server:
$http = new GuzzleHttp\Client; $response = $http->post('http://your-app.com/oauth/token', [ 'form_params' => [ 'grant_type' => 'password', 'client_id' => 'client-id', 'client_secret' => 'client-secret', 'username' => 'taylor@laravel.com', 'password' => 'my-password', 'scope' => '', ],]); return json_decode((string) $response->getBody(), true);
{tip} By default, access Tokens are valid for a long time. You can Configure the validity time of the access token as needed.
Request all scopes
When using the password authorization mechanism, you can request the scope parameter*
to authorize all ranges of tokens supported by the application. If your request contains parameters with scope *
, the can
method on the token instance will always return true
. Authorizations of this scope can only be assigned to tokens issued when authorizing using password
:
$response = $http->post('http://your-app.com/oauth/token', [ 'form_params' => [ 'grant_type' => 'password', 'client_id' => 'client-id', 'client_secret' => 'client-secret', 'username' => 'taylor@laravel.com', 'password' => 'my-password', 'scope' => '*', ], ]);
Custom username field
When using password authorization, Passport uses email
as the "username" by default. However, you can customize the username field by defining a findForPassport
method on the model:
<?php namespace App; use Laravel\Passport\HasApiTokens; use Illuminate\Notifications\Notifiable; use Illuminate\Foundation\Auth\User as Authenticatable; class User extends Authenticatable{ use HasApiTokens, Notifiable; /** * 通过用户名找到对应的用户信息 * * @param string $username * @return \App\User */ public function findForPassport($username) { return $this->where('username', $username)->first(); } }
hidden Implicit authorization token
Implicit authorization is similar to authorization code authorization, but it only returns the token to the client without exchanging the authorization code. This authorization is most commonly used for JavaScript or mobile applications that cannot store client credentials securely. Enable this authorization by calling the enableImplicitGrant
method in AuthServiceProvider
:
/** * 注册认证 / 授权服务 * * @return void */ public function boot(){ $this->registerPolicies(); Passport::routes(); Passport::enableImplicitGrant(); }
After calling the above method to enable authorization, developers can use their client ID to access the authorization from the application The program requests an access token. The connected application should make a redirect request to your application's /oauth/authorize
route, as shown below:
Route::get('/redirect', function () { $query = http_build_query([ 'client_id' => 'client-id', 'redirect_uri' => 'http://example.com/callback', 'response_type' => 'token', 'scope' => '', ]); return redirect('http://your-app.com/oauth/authorize?'.$query); });
{tip} Note,
The /oauth/authorize
route has already been defined in thePassport::routes
method, so there is no need to manually define this route again.
Client Credential Grant Token
Client Credential Grant is suitable for machine-to-machine authentication. For example, you can use this authorization to perform maintenance tasks through the API.
Before client credential authorization, you need to create a client credential authorization client. You can use the --client
parameter of the passport:client
command to Create:
php artisan passport:client --client
Next, to use this authorization, you first need to add the new middleware in the $routeMiddleware
variable of app/Http/Kernel.php
File:
use Laravel\Passport\Http\Middleware\CheckClientCredentials; protected $routeMiddleware = [ 'client' => CheckClientCredentials::class, ];
Then, append this middleware to the route:
Route::get('/orders', function (Request $request) { ... })->middleware('client');
If you want to limit access to the route to a certain scope, you can add client
Provide a comma-separated list of required scopes when the middleware is attached to a route:
Route::get('/orders', function (Request $request) { ... })->middleware('client:check-status,your-scope');
Get the token
by requesting oauth/token
The interface sends a request to obtain the token:
$guzzle = new GuzzleHttp\Client; $response = $guzzle->post('http://your-app.com/oauth/token', [ 'form_params' => [ 'grant_type' => 'client_credentials', 'client_id' => 'client-id', 'client_secret' => 'client-secret', 'scope' => 'your-scope', ],]); return json_decode((string) $response->getBody(), true)['access_token'];
Personal access token
Sometimes, the user needs to be in the Issue an access token to yourself without going through the traditional authorization code redirection process. Allowing users to issue tokens to themselves through the application UI can help users experience your API, or it can be used as a simpler way to issue access tokens.
{note} The personal access token is permanently valid, and its life cycle will not be modified even if the
tokensExpireIn
andrefreshTokensExpireIn
methods are used.
Create a Personal Access Client
Before your application issues a Personal Access Token, You need to bring the --personal
parameter after the passport:client
command to create the corresponding client. If you have already run the passport:install
command, you do not need to run this command again:
php artisan passport:client --personal
If you have already created a Personal Access client, you can do this by calling AuthServiceProvider
in the personalAccessClientId
method to enable:
/** * 注册认证 / 授权服务 * * @return void */ public function boot(){ $this->registerPolicies(); Passport::routes(); Passport::personalAccessClientId('client-id'); }
Manage Personal Access Token
After creating a personal access client, you can use the createToken
method on the User
model instance to issue a token for a given user. The createToken
method accepts the name of the token as its first argument and an optional scope array as its second argument:
$user = App\User::find(1); // 创建没有作用域的访问令牌... $token = $user->createToken('Token Name')->accessToken; // 创建有作用域的访问令牌... $token = $user->createToken('My Token', ['place-orders'])->accessToken;
JSON API
Passport also has a JSON API for managing personal access tokens, which you can pair with your own front end to provide users with a dashboard for managing personal access tokens. Below we describe all API interfaces for managing personal access tokens. For convenience, we use Axios to demonstrate making HTTP requests to the API interface. The
JSON API is protected by web
and auth
middleware; therefore, it can only be called from within your own application. It cannot be called from external sources.
{tip} If you don’t want to implement your own front-end interface for personal access token management, you can follow Quick Start with Front-End to build a fully functional front-end interface in a few minutes.
GET /oauth/scopes
This route returns all scopes defined in the application . You can use this route to list the scopes that a user may be assigned to personal access tokens:
axios.get('/oauth/scopes') .then(response => { console.log(response.data); });
GET /oauth/personal-access-tokens
This route returns all personal access tokens created by the authenticated user. This is mainly used to list all users' tokens so they can edit or delete them:
axios.get('/oauth/personal-access-tokens') .then(response => { console.log(response.data); });
POST /oauth/personal-access-tokens
This route is used to create a new personal access token. It requires two pieces of data: the name
and scpoe
of the token:
const data = { name: 'Token Name', scopes: []}; axios.post('/oauth/personal-access-tokens', data) .then(response => { console.log(response.data.accessToken); }) .catch (response => { // 列出响应中错误... });
##DELETE /oauth/personal-access-tokens /{token-id}
This route can be used to delete personal access tokens: axios.delete('/oauth/personal-access-tokens/' + tokenId);
Passport contains a verification protection mechanism that can verify the access token passed in the request Card. After configuring
api's watcher to use the passport
driver, you only need to specify the auth:api
middleware on any route that requires a valid access token: Route::get('/user', function () {
//
})->middleware('auth:api');
Authorization
as theBearer token. For example, when using the Guzzle HTTP library:
$response = $client->request('GET', '/api/user', [ 'headers' => [ 'Accept' => 'application/json', 'Authorization' => 'Bearer '.$accessToken, ], ]);
Token Scope
Scope allows API clients to request specific permissions when requesting account authorization. For example, if you are building an e-commerce application, not all API applications that connect to it will need the ability to place orders. You can allow connected API applications to only be authorized to access order shipping status. In other words, scoping allows users of an application to limit the actions that third-party applications can perform.
Define the scope
You can boot## of
AuthServiceProvider # Use the
Passport::tokensCan method to define the scope of the API.
tokensCan The method accepts an array containing the scope name and description as parameters. The scope description will be displayed directly to the user on the authorization confirmation page. You can define it to whatever you need:
use Laravel\Passport\Passport; Passport::tokensCan([ 'place-orders' => 'Place orders', 'check-status' => 'Check order status', ]);Default Scope If the client does not request any specific scope, you can use
Passport::setDefaultScope# in the boot
method of AuthServiceProvider
## Method to define the default scope. use Laravel\Passport\Passport;Passport::setDefaultScope([
'check-status',
'place-orders',
]);
When requesting an access token using an authorization code, the connected application needs to specify the required scope for the
scope parameter. scope
When the parameter contains multiple scopes, use spaces to separate the names: Route::get('/redirect', function () {
$query = http_build_query([
'client_id' => 'client-id',
'redirect_uri' => 'http://example.com/callback',
'response_type' => 'code',
'scope' => 'place-orders check-status',
]);
return redirect('http://your-app.com/oauth/authorize?'.$query);});
Use
When thecreateToken method of the User
model issues a personal access token, you can pass the array of required scopes as the second parameter to this method: $token = $user->createToken('My Token', ['place-orders'])->accessToken;
Passport contains two middlewares that can be used to verify that incoming requests contain a token to access the specified scope. Before use, you need to add the following middleware to the
$routeMiddleware attribute of the app/Http/Kernel.php
file: 'scopes' => \Laravel\Passport\Http\Middleware\CheckScopes::class,
'scope' => \Laravel\Passport\Http\Middleware\CheckForAnyScope::class,
Routes can use the
scopes middleware to check whether the current request has the specified all
scopes: Route::get('/orders', function () {
// Access token has both "check-status" and "place-orders" scopes...
})->middleware('scopes:check-status,place-orders');
Routes can use the
scope middleware to check whether the current request has the specified any
scope: Route::get('/orders', function () {
// 访问令牌具有 "check-status" 或 "place-orders" 作用域...
})->middleware('scope:check-status,place-orders');
Check the scope on the token instance
Even if the request containing the access token verification has been authenticated by the application, you can still use the current authorization User
## on the instance #tokenCan method to verify that the token has the specified scope:
use Illuminate\Http\Request; Route::get('/orders', function (Request $request) { if ($request->user()->tokenCan('place-orders')) { // } });Additional scope method
scopeIds method will return Array of all defined IDs/names:
Laravel\Passport\Passport::scopeIds();
scopes The method will return an
Laravel\Passport\Scope instance containing an array of all defined scopes:
Laravel\Passport\Passport::scopes();
scopesFor method will return an array of
Laravel\Passport\Scope instances that match the given ID/name:
Laravel\Passport\Passport::scopesFor(['place-orders', 'check-status']);You can use
The hasScope method determines whether a given scope has been defined:
Laravel\Passport\Passport::hasScope('place-orders');Use JavaScript to access the API When building an API, being able to access your own API through JavaScript applications will bring great convenience to the development process. This approach to API development allows you to use your own application's API and others' shared APIs. Your web app, mobile app, third-party apps, and any SDKs you might publish on various package managers will likely use the same API. Normally, if you want to use the API in a JavaScript application, you need to manually send the access token and pass it to the application. However, Passport has a middleware that handles this problem. Just add the
CreateFreshApiToken middleware to the
web middleware group in the
app/Http/Kernel.php file:
'web' => [ // 其他中间件... \Laravel\Passport\Http\Middleware\CreateFreshApiToken::class, ],
{note} You should ensure that theThis Passport middleware will add aEncryptCookies
middleware is listed before the
CreateFreshApiTokenmiddleware in your middleware stack.
laravel_token cookie to all your outbound requests. This cookie will contain an encrypted JWT that Passport will use to authenticate API requests from JavaScript applications. At this point, you can make requests to your application's API without explicitly passing the access token:
axios.get('/api/user') .then(response => { console.log(response.data); });Custom Cookie NameIf needed, you can Use the
Passport::cookie method in the
boot method of
AuthServiceProvider to customize the name of the
laravel_token cookie.
/** * 注册认证 / 授权服务 * * @return void */ public function boot(){ $this->registerPolicies(); Passport::routes(); Passport::cookie('custom_name'); }CSRF ProtectionWhen using this authorization method, the default Laravel JavaScript scaffolding will cause Axios to send
X-CSRF-TOKEN and
X-Requested-With Request header. Additionally, you must ensure that the HTML meta tag tag contains the CSRF token:
// In your application layout... <meta name="csrf-token" content="{{ csrf_token() }}"> // Laravel's JavaScript scaffolding... window.axios.defaults.headers.common = { 'X-Requested-With': 'XMLHttpRequest', };
Events
Passport triggers events when access tokens and refresh tokens are issued. You can append listeners for these events in your application's EventServiceProvider
, and revoke or modify other tokens in the listener:
/** * 应用程序事件监听映射 * * @var array */ protected $listen = [ 'Laravel\Passport\Events\AccessTokenCreated' => [ 'App\Listeners\RevokeOldTokens', ], 'Laravel\Passport\Events\RefreshTokenCreated' => [ 'App\Listeners\PruneOldTokens', ], ];
Test
Passport's actingAs
method can specify the currently authenticated user and its scope. actingAs
The first parameter of the method is the user instance, and the second parameter is the user token scope array:
use App\User; use Laravel\Passport\Passport; public function testServerCreation(){ Passport::actingAs( factory(User::class)->create(), ['create-servers'] ); $response = $this->post('/api/create-server'); $response->assertStatus(201); }