Files
laravelDocScrappy/output/12.x/sanctum.md
2025-09-02 15:19:23 +02:00

1079 lines
31 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Laravel Sanctum
* Introduction
* How it Works
* Installation
* Configuration
* Overriding Default Models
* API Token Authentication
* Issuing API Tokens
* Token Abilities
* Protecting Routes
* Revoking Tokens
* Token Expiration
* SPA Authentication
* Configuration
* Authenticating
* Protecting Routes
* Authorizing Private Broadcast Channels
* Mobile Application Authentication
* Issuing API Tokens
* Protecting Routes
* Revoking Tokens
* Testing
## Introduction
[Laravel Sanctum](https://github.com/laravel/sanctum) provides a featherweight
authentication system for SPAs (single page applications), mobile
applications, and simple, token based APIs. Sanctum allows each user of your
application to generate multiple API tokens for their account. These tokens
may be granted abilities / scopes which specify which actions the tokens are
allowed to perform.
### How it Works
Laravel Sanctum exists to solve two separate problems. Let's discuss each
before digging deeper into the library.
#### API Tokens
First, Sanctum is a simple package you may use to issue API tokens to your
users without the complication of OAuth. This feature is inspired by GitHub
and other applications which issue "personal access tokens". For example,
imagine the "account settings" of your application has a screen where a user
may generate an API token for their account. You may use Sanctum to generate
and manage those tokens. These tokens typically have a very long expiration
time (years), but may be manually revoked by the user anytime.
Laravel Sanctum offers this feature by storing user API tokens in a single
database table and authenticating incoming HTTP requests via the
`Authorization` header which should contain a valid API token.
#### SPA Authentication
Second, Sanctum exists to offer a simple way to authenticate single page
applications (SPAs) that need to communicate with a Laravel powered API. These
SPAs might exist in the same repository as your Laravel application or might
be an entirely separate repository, such as an SPA created using Next.js or
Nuxt.
For this feature, Sanctum does not use tokens of any kind. Instead, Sanctum
uses Laravel's built-in cookie based session authentication services.
Typically, Sanctum utilizes Laravel's `web` authentication guard to accomplish
this. This provides the benefits of CSRF protection, session authentication,
as well as protects against leakage of the authentication credentials via XSS.
Sanctum will only attempt to authenticate using cookies when the incoming
request originates from your own SPA frontend. When Sanctum examines an
incoming HTTP request, it will first check for an authentication cookie and,
if none is present, Sanctum will then examine the `Authorization` header for a
valid API token.
It is perfectly fine to use Sanctum only for API token authentication or only
for SPA authentication. Just because you use Sanctum does not mean you are
required to use both features it offers.
## Installation
You may install Laravel Sanctum via the `install:api` Artisan command:
1php artisan install:api
php artisan install:api
Next, if you plan to utilize Sanctum to authenticate an SPA, please refer to
the SPA Authentication section of this documentation.
## Configuration
### Overriding Default Models
Although not typically required, you are free to extend the
`PersonalAccessToken` model used internally by Sanctum:
1use Laravel\Sanctum\PersonalAccessToken as SanctumPersonalAccessToken;
2 
3class PersonalAccessToken extends SanctumPersonalAccessToken
4{
5 // ...
6}
use Laravel\Sanctum\PersonalAccessToken as SanctumPersonalAccessToken;
class PersonalAccessToken extends SanctumPersonalAccessToken
{
// ...
}
Then, you may instruct Sanctum to use your custom model via the
`usePersonalAccessTokenModel` method provided by Sanctum. Typically, you
should call this method in the `boot` method of your application's
`AppServiceProvider` file:
1use App\Models\Sanctum\PersonalAccessToken;
2use Laravel\Sanctum\Sanctum;
3 
4/**
5 * Bootstrap any application services.
6 */
7public function boot(): void
8{
9 Sanctum::usePersonalAccessTokenModel(PersonalAccessToken::class);
10}
use App\Models\Sanctum\PersonalAccessToken;
use Laravel\Sanctum\Sanctum;
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Sanctum::usePersonalAccessTokenModel(PersonalAccessToken::class);
}
## API Token Authentication
You should not use API tokens to authenticate your own first-party SPA.
Instead, use Sanctum's built-in SPA authentication features.
### Issuing API Tokens
Sanctum allows you to issue API tokens / personal access tokens that may be
used to authenticate API requests to your application. When making requests
using API tokens, the token should be included in the `Authorization` header
as a `Bearer` token.
To begin issuing tokens for users, your User model should use the
`Laravel\Sanctum\HasApiTokens` trait:
1use Laravel\Sanctum\HasApiTokens;
2 
3class User extends Authenticatable
4{
5 use HasApiTokens, HasFactory, Notifiable;
6}
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
}
To issue a token, you may use the `createToken` method. The `createToken`
method returns a `Laravel\Sanctum\NewAccessToken` instance. API tokens are
hashed using SHA-256 hashing before being stored in your database, but you may
access the plain-text value of the token using the `plainTextToken` property
of the `NewAccessToken` instance. You should display this value to the user
immediately after the token has been created:
1use Illuminate\Http\Request;
2 
3Route::post('/tokens/create', function (Request $request) {
4 $token = $request->user()->createToken($request->token_name);
5 
6 return ['token' => $token->plainTextToken];
7});
use Illuminate\Http\Request;
Route::post('/tokens/create', function (Request $request) {
$token = $request->user()->createToken($request->token_name);
return ['token' => $token->plainTextToken];
});
You may access all of the user's tokens using the `tokens` Eloquent
relationship provided by the `HasApiTokens` trait:
1foreach ($user->tokens as $token) {
2 // ...
3}
foreach ($user->tokens as $token) {
// ...
}
### Token Abilities
Sanctum allows you to assign "abilities" to tokens. Abilities serve a similar
purpose as OAuth's "scopes". You may pass an array of string abilities as the
second argument to the `createToken` method:
1return $user->createToken('token-name', ['server:update'])->plainTextToken;
return $user->createToken('token-name', ['server:update'])->plainTextToken;
When handling an incoming request authenticated by Sanctum, you may determine
if the token has a given ability using the `tokenCan` or `tokenCant` methods:
1if ($user->tokenCan('server:update')) {
2 // ...
3}
4 
5if ($user->tokenCant('server:update')) {
6 // ...
7}
if ($user->tokenCan('server:update')) {
// ...
}
if ($user->tokenCant('server:update')) {
// ...
}
#### Token Ability Middleware
Sanctum also includes two middleware that may be used to verify that an
incoming request is authenticated with a token that has been granted a given
ability. To get started, define the following middleware aliases in your
application's `bootstrap/app.php` file:
1use Laravel\Sanctum\Http\Middleware\CheckAbilities;
2use Laravel\Sanctum\Http\Middleware\CheckForAnyAbility;
3 
4->withMiddleware(function (Middleware $middleware) {
5 $middleware->alias([
6 'abilities' => CheckAbilities::class,
7 'ability' => CheckForAnyAbility::class,
8 ]);
9})
use Laravel\Sanctum\Http\Middleware\CheckAbilities;
use Laravel\Sanctum\Http\Middleware\CheckForAnyAbility;
->withMiddleware(function (Middleware $middleware) {
$middleware->alias([
'abilities' => CheckAbilities::class,
'ability' => CheckForAnyAbility::class,
]);
})
The `abilities` middleware may be assigned to a route to verify that the
incoming request's token has all of the listed abilities:
1Route::get('/orders', function () {
2 // Token has both "check-status" and "place-orders" abilities...
3})->middleware(['auth:sanctum', 'abilities:check-status,place-orders']);
Route::get('/orders', function () {
// Token has both "check-status" and "place-orders" abilities...
})->middleware(['auth:sanctum', 'abilities:check-status,place-orders']);
The `ability` middleware may be assigned to a route to verify that the
incoming request's token has _at least one_ of the listed abilities:
1Route::get('/orders', function () {
2 // Token has the "check-status" or "place-orders" ability...
3})->middleware(['auth:sanctum', 'ability:check-status,place-orders']);
Route::get('/orders', function () {
// Token has the "check-status" or "place-orders" ability...
})->middleware(['auth:sanctum', 'ability:check-status,place-orders']);
#### First-Party UI Initiated Requests
For convenience, the `tokenCan` method will always return `true` if the
incoming authenticated request was from your first-party SPA and you are using
Sanctum's built-in SPA authentication.
However, this does not necessarily mean that your application has to allow the
user to perform the action. Typically, your application's [authorization
policies](/docs/12.x/authorization#creating-policies) will determine if the
token has been granted the permission to perform the abilities as well as
check that the user instance itself should be allowed to perform the action.
For example, if we imagine an application that manages servers, this might
mean checking that the token is authorized to update servers **and** that the
server belongs to the user:
1return $request->user()->id === $server->user_id &&
2 $request->user()->tokenCan('server:update')
return $request->user()->id === $server->user_id &&
$request->user()->tokenCan('server:update')
At first, allowing the `tokenCan` method to be called and always return `true`
for first-party UI initiated requests may seem strange; however, it is
convenient to be able to always assume an API token is available and can be
inspected via the `tokenCan` method. By taking this approach, you may always
call the `tokenCan` method within your application's authorization policies
without worrying about whether the request was triggered from your
application's UI or was initiated by one of your API's third-party consumers.
### Protecting Routes
To protect routes so that all incoming requests must be authenticated, you
should attach the `sanctum` authentication guard to your protected routes
within your `routes/web.php` and `routes/api.php` route files. This guard will
ensure that incoming requests are authenticated as either stateful, cookie
authenticated requests or contain a valid API token header if the request is
from a third party.
You may be wondering why we suggest that you authenticate the routes within
your application's `routes/web.php` file using the `sanctum` guard. Remember,
Sanctum will first attempt to authenticate incoming requests using Laravel's
typical session authentication cookie. If that cookie is not present then
Sanctum will attempt to authenticate the request using a token in the
request's `Authorization` header. In addition, authenticating all requests
using Sanctum ensures that we may always call the `tokenCan` method on the
currently authenticated user instance:
1use Illuminate\Http\Request;
2 
3Route::get('/user', function (Request $request) {
4 return $request->user();
5})->middleware('auth:sanctum');
use Illuminate\Http\Request;
Route::get('/user', function (Request $request) {
return $request->user();
})->middleware('auth:sanctum');
### Revoking Tokens
You may "revoke" tokens by deleting them from your database using the `tokens`
relationship that is provided by the `Laravel\Sanctum\HasApiTokens` trait:
1// Revoke all tokens...
2$user->tokens()->delete();
3 
4// Revoke the token that was used to authenticate the current request...
5$request->user()->currentAccessToken()->delete();
6 
7// Revoke a specific token...
8$user->tokens()->where('id', $tokenId)->delete();
// Revoke all tokens...
$user->tokens()->delete();
// Revoke the token that was used to authenticate the current request...
$request->user()->currentAccessToken()->delete();
// Revoke a specific token...
$user->tokens()->where('id', $tokenId)->delete();
### Token Expiration
By default, Sanctum tokens never expire and may only be invalidated by
revoking the token. However, if you would like to configure an expiration time
for your application's API tokens, you may do so via the `expiration`
configuration option defined in your application's `sanctum` configuration
file. This configuration option defines the number of minutes until an issued
token will be considered expired:
1'expiration' => 525600,
'expiration' => 525600,
If you would like to specify the expiration time of each token independently,
you may do so by providing the expiration time as the third argument to the
`createToken` method:
1return $user->createToken(
2 'token-name', ['*'], now()->addWeek()
3)->plainTextToken;
return $user->createToken(
'token-name', ['*'], now()->addWeek()
)->plainTextToken;
If you have configured a token expiration time for your application, you may
also wish to [schedule a task](/docs/12.x/scheduling) to prune your
application's expired tokens. Thankfully, Sanctum includes a `sanctum:prune-
expired` Artisan command that you may use to accomplish this. For example, you
may configure a scheduled task to delete all expired token database records
that have been expired for at least 24 hours:
1use Illuminate\Support\Facades\Schedule;
2 
3Schedule::command('sanctum:prune-expired --hours=24')->daily();
use Illuminate\Support\Facades\Schedule;
Schedule::command('sanctum:prune-expired --hours=24')->daily();
## SPA Authentication
Sanctum also exists to provide a simple method of authenticating single page
applications (SPAs) that need to communicate with a Laravel powered API. These
SPAs might exist in the same repository as your Laravel application or might
be an entirely separate repository.
For this feature, Sanctum does not use tokens of any kind. Instead, Sanctum
uses Laravel's built-in cookie based session authentication services. This
approach to authentication provides the benefits of CSRF protection, session
authentication, as well as protects against leakage of the authentication
credentials via XSS.
In order to authenticate, your SPA and API must share the same top-level
domain. However, they may be placed on different subdomains. Additionally, you
should ensure that you send the `Accept: application/json` header and either
the `Referer` or `Origin` header with your request.
### Configuration
#### Configuring Your First-Party Domains
First, you should configure which domains your SPA will be making requests
from. You may configure these domains using the `stateful` configuration
option in your `sanctum` configuration file. This configuration setting
determines which domains will maintain "stateful" authentication using Laravel
session cookies when making requests to your API.
To assist you in setting up your first-party stateful domains, Sanctum
provides two helper functions that you can include in the configuration.
First, `Sanctum::currentApplicationUrlWithPort()` will return the current
application URL from the `APP_URL` environment variable, and
`Sanctum::currentRequestHost()` will inject a placeholder into the stateful
domain list which, at runtime, will be replaced by the host from the current
request so that all requests with the same domain are considered stateful.
If you are accessing your application via a URL that includes a port
(`127.0.0.1:8000`), you should ensure that you include the port number with
the domain.
#### Sanctum Middleware
Next, you should instruct Laravel that incoming requests from your SPA can
authenticate using Laravel's session cookies, while still allowing requests
from third parties or mobile applications to authenticate using API tokens.
This can be easily accomplished by invoking the `statefulApi` middleware
method in your application's `bootstrap/app.php` file:
1->withMiddleware(function (Middleware $middleware) {
2 $middleware->statefulApi();
3})
->withMiddleware(function (Middleware $middleware) {
$middleware->statefulApi();
})
#### CORS and Cookies
If you are having trouble authenticating with your application from an SPA
that executes on a separate subdomain, you have likely misconfigured your CORS
(Cross-Origin Resource Sharing) or session cookie settings.
The `config/cors.php` configuration file is not published by default. If you
need to customize Laravel's CORS options, you should publish the complete
`cors` configuration file using the `config:publish` Artisan command:
1php artisan config:publish cors
php artisan config:publish cors
Next, you should ensure that your application's CORS configuration is
returning the `Access-Control-Allow-Credentials` header with a value of
`True`. This may be accomplished by setting the `supports_credentials` option
within your application's `config/cors.php` configuration file to `true`.
In addition, you should enable the `withCredentials` and `withXSRFToken`
options on your application's global `axios` instance. Typically, this should
be performed in your `resources/js/bootstrap.js` file. If you are not using
Axios to make HTTP requests from your frontend, you should perform the
equivalent configuration on your own HTTP client:
1axios.defaults.withCredentials = true;
2axios.defaults.withXSRFToken = true;
axios.defaults.withCredentials = true;
axios.defaults.withXSRFToken = true;
Finally, you should ensure your application's session cookie domain
configuration supports any subdomain of your root domain. You may accomplish
this by prefixing the domain with a leading `.` within your application's
`config/session.php` configuration file:
1'domain' => '.domain.com',
'domain' => '.domain.com',
### Authenticating
#### CSRF Protection
To authenticate your SPA, your SPA's "login" page should first make a request
to the `/sanctum/csrf-cookie` endpoint to initialize CSRF protection for the
application:
1axios.get('/sanctum/csrf-cookie').then(response => {
2 // Login...
3});
axios.get('/sanctum/csrf-cookie').then(response => {
// Login...
});
During this request, Laravel will set an `XSRF-TOKEN` cookie containing the
current CSRF token. This token should then be URL decoded and passed in an
`X-XSRF-TOKEN` header on subsequent requests, which some HTTP client libraries
like Axios and the Angular HttpClient will do automatically for you. If your
JavaScript HTTP library does not set the value for you, you will need to
manually set the `X-XSRF-TOKEN` header to match the URL decoded value of the
`XSRF-TOKEN` cookie that is set by this route.
#### Logging In
Once CSRF protection has been initialized, you should make a `POST` request to
your Laravel application's `/login` route. This `/login` route may be
[implemented manually](/docs/12.x/authentication#authenticating-users) or
using a headless authentication package like [Laravel
Fortify](/docs/12.x/fortify).
If the login request is successful, you will be authenticated and subsequent
requests to your application's routes will automatically be authenticated via
the session cookie that the Laravel application issued to your client. In
addition, since your application already made a request to the `/sanctum/csrf-
cookie` route, subsequent requests should automatically receive CSRF
protection as long as your JavaScript HTTP client sends the value of the
`XSRF-TOKEN` cookie in the `X-XSRF-TOKEN` header.
Of course, if your user's session expires due to lack of activity, subsequent
requests to the Laravel application may receive a 401 or 419 HTTP error
response. In this case, you should redirect the user to your SPA's login page.
You are free to write your own `/login` endpoint; however, you should ensure
that it authenticates the user using the standard, [session based
authentication services that Laravel
provides](/docs/12.x/authentication#authenticating-users). Typically, this
means using the `web` authentication guard.
### Protecting Routes
To protect routes so that all incoming requests must be authenticated, you
should attach the `sanctum` authentication guard to your API routes within
your `routes/api.php` file. This guard will ensure that incoming requests are
authenticated as either stateful authenticated requests from your SPA or
contain a valid API token header if the request is from a third party:
1use Illuminate\Http\Request;
2 
3Route::get('/user', function (Request $request) {
4 return $request->user();
5})->middleware('auth:sanctum');
use Illuminate\Http\Request;
Route::get('/user', function (Request $request) {
return $request->user();
})->middleware('auth:sanctum');
### Authorizing Private Broadcast Channels
If your SPA needs to authenticate with [private / presence broadcast
channels](/docs/12.x/broadcasting#authorizing-channels), you should remove the
`channels` entry from the `withRouting` method contained in your application's
`bootstrap/app.php` file. Instead, you should invoke the `withBroadcasting`
method so that you may specify the correct middleware for your application's
broadcasting routes:
1return Application::configure(basePath: dirname(__DIR__))
2 ->withRouting(
3 web: __DIR__.'/../routes/web.php',
4 // ...
5 )
6 ->withBroadcasting(
7 __DIR__.'/../routes/channels.php',
8 ['prefix' => 'api', 'middleware' => ['api', 'auth:sanctum']],
9 )
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__.'/../routes/web.php',
// ...
)
->withBroadcasting(
__DIR__.'/../routes/channels.php',
['prefix' => 'api', 'middleware' => ['api', 'auth:sanctum']],
)
Next, in order for Pusher's authorization requests to succeed, you will need
to provide a custom Pusher `authorizer` when initializing [Laravel
Echo](/docs/12.x/broadcasting#client-side-installation). This allows your
application to configure Pusher to use the `axios` instance that is properly
configured for cross-domain requests:
1window.Echo = new Echo({
2 broadcaster: "pusher",
3 cluster: import.meta.env.VITE_PUSHER_APP_CLUSTER,
4 encrypted: true,
5 key: import.meta.env.VITE_PUSHER_APP_KEY,
6 authorizer: (channel, options) => {
7 return {
8 authorize: (socketId, callback) => {
9 axios.post('/api/broadcasting/auth', {
10 socket_id: socketId,
11 channel_name: channel.name
12 })
13 .then(response => {
14 callback(false, response.data);
15 })
16 .catch(error => {
17 callback(true, error);
18 });
19 }
20 };
21 },
22})
window.Echo = new Echo({
broadcaster: "pusher",
cluster: import.meta.env.VITE_PUSHER_APP_CLUSTER,
encrypted: true,
key: import.meta.env.VITE_PUSHER_APP_KEY,
authorizer: (channel, options) => {
return {
authorize: (socketId, callback) => {
axios.post('/api/broadcasting/auth', {
socket_id: socketId,
channel_name: channel.name
})
.then(response => {
callback(false, response.data);
})
.catch(error => {
callback(true, error);
});
}
};
},
})
## Mobile Application Authentication
You may also use Sanctum tokens to authenticate your mobile application's
requests to your API. The process for authenticating mobile application
requests is similar to authenticating third-party API requests; however, there
are small differences in how you will issue the API tokens.
### Issuing API Tokens
To get started, create a route that accepts the user's email / username,
password, and device name, then exchanges those credentials for a new Sanctum
token. The "device name" given to this endpoint is for informational purposes
and may be any value you wish. In general, the device name value should be a
name the user would recognize, such as "Nuno's iPhone 12".
Typically, you will make a request to the token endpoint from your mobile
application's "login" screen. The endpoint will return the plain-text API
token which may then be stored on the mobile device and used to make
additional API requests:
1use App\Models\User;
2use Illuminate\Http\Request;
3use Illuminate\Support\Facades\Hash;
4use Illuminate\Validation\ValidationException;
5 
6Route::post('/sanctum/token', function (Request $request) {
7 $request->validate([
8 'email' => 'required|email',
9 'password' => 'required',
10 'device_name' => 'required',
11 ]);
12 
13 $user = User::where('email', $request->email)->first();
14 
15 if (! $user || ! Hash::check($request->password, $user->password)) {
16 throw ValidationException::withMessages([
17 'email' => ['The provided credentials are incorrect.'],
18 ]);
19 }
20 
21 return $user->createToken($request->device_name)->plainTextToken;
22});
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\ValidationException;
Route::post('/sanctum/token', function (Request $request) {
$request->validate([
'email' => 'required|email',
'password' => 'required',
'device_name' => 'required',
]);
$user = User::where('email', $request->email)->first();
if (! $user || ! Hash::check($request->password, $user->password)) {
throw ValidationException::withMessages([
'email' => ['The provided credentials are incorrect.'],
]);
}
return $user->createToken($request->device_name)->plainTextToken;
});
When the mobile application uses the token to make an API request to your
application, it should pass the token in the `Authorization` header as a
`Bearer` token.
When issuing tokens for a mobile application, you are also free to specify
token abilities.
### Protecting Routes
As previously documented, you may protect routes so that all incoming requests
must be authenticated by attaching the `sanctum` authentication guard to the
routes:
1Route::get('/user', function (Request $request) {
2 return $request->user();
3})->middleware('auth:sanctum');
Route::get('/user', function (Request $request) {
return $request->user();
})->middleware('auth:sanctum');
### Revoking Tokens
To allow users to revoke API tokens issued to mobile devices, you may list
them by name, along with a "Revoke" button, within an "account settings"
portion of your web application's UI. When the user clicks the "Revoke"
button, you can delete the token from the database. Remember, you can access a
user's API tokens via the `tokens` relationship provided by the
`Laravel\Sanctum\HasApiTokens` trait:
1// Revoke all tokens...
2$user->tokens()->delete();
3 
4// Revoke a specific token...
5$user->tokens()->where('id', $tokenId)->delete();
// Revoke all tokens...
$user->tokens()->delete();
// Revoke a specific token...
$user->tokens()->where('id', $tokenId)->delete();
## Testing
While testing, the `Sanctum::actingAs` method may be used to authenticate a
user and specify which abilities should be granted to their token:
Pest PHPUnit
1use App\Models\User;
2use Laravel\Sanctum\Sanctum;
3 
4test('task list can be retrieved', function () {
5 Sanctum::actingAs(
6 User::factory()->create(),
7 ['view-tasks']
8 );
9 
10 $response = $this->get('/api/task');
11 
12 $response->assertOk();
13});
use App\Models\User;
use Laravel\Sanctum\Sanctum;
test('task list can be retrieved', function () {
Sanctum::actingAs(
User::factory()->create(),
['view-tasks']
);
$response = $this->get('/api/task');
$response->assertOk();
});
1use App\Models\User;
2use Laravel\Sanctum\Sanctum;
3 
4public function test_task_list_can_be_retrieved(): void
5{
6 Sanctum::actingAs(
7 User::factory()->create(),
8 ['view-tasks']
9 );
10 
11 $response = $this->get('/api/task');
12 
13 $response->assertOk();
14}
use App\Models\User;
use Laravel\Sanctum\Sanctum;
public function test_task_list_can_be_retrieved(): void
{
Sanctum::actingAs(
User::factory()->create(),
['view-tasks']
);
$response = $this->get('/api/task');
$response->assertOk();
}
If you would like to grant all abilities to the token, you should include `*`
in the ability list provided to the `actingAs` method:
1Sanctum::actingAs(
2 User::factory()->create(),
3 ['*']
4);
Sanctum::actingAs(
User::factory()->create(),
['*']
);