I have successfully set up Sanctum on Laravel 8. However, when I try to use Postman with the bearer token obtained from the personal_access_tokens table, I encounter the following error message. Could it be the stateful setting? As I am not communicating to the API form the same domain but from Postman and then my real project will be sending data from another window computer to my website. I have been for 4 days on this, I cannot find an answer to the issue.
"I would like to reassure you that the page is not undergoing maintenance(php artisan up)."
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html>
<head>
<title>503 Service Unavailable</title>
</head>
<body>
<h1>Service Unavailable</h1>
<p>The server is temporarily unable to service your
request due to maintenance downtime or capacity
problems. Please try again later.</p>
</body>
</html>
api.php:
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\V2\Api\KeywordsController;
Route::middleware(['auth:sanctum', 'abilities:db:view,db:update,db:store'])->group(function () {
Route::get('fetch-keyword', [KeywordsController::class, 'fetchKeyword']);
Route::put('update-keyword/{keywordName}', [KeywordsController::class, 'updateKeyword']);
});
auth.php:
<?php
return [
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'sanctum',
'provider' => 'users',
'hash' => false,
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
],
'verification' => [
'expire' => 1440,
],
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 180,
'throttle' => 60,
],
],
'password_timeout' => 10800,
];
Sanctum.php:
<?php
use Laravel\Sanctum\Sanctum;
return [
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(
'%s%s',
'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1',
Sanctum::currentApplicationUrlWithPort()
))),
'guard' => ['api'],
'expiration' => null,
'middleware' => [
'verify_csrf_token' => App\Http\Middleware\VerifyCsrfToken::class,
'encrypt_cookies' => App\Http\Middleware\EncryptCookies::class,
],
];
Traits in the User Model:
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Paddle\Billable;
use Spatie\Permission\Traits\HasRoles;
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable implements MustVerifyEmail
{
use HasApiTokens, HasFactory, Notifiable, Billable, HasRoles;
.....more code not attached
Kernal.php:
<?php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
protected $middleware = [
// \App\Http\Middleware\TrustHosts::class,
\App\Http\Middleware\TrustProxies::class,
\Illuminate\Http\Middleware\HandleCors::class,
\App\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
];
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,
],
'api' => [
'throttle:60,1',
\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
\Illuminate\Routing\Middleware\ThrottleRequests::class.':api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
'role' => \Spatie\Permission\Middlewares\RoleMiddleware::class,
'abilities' => \Laravel\Sanctum\Http\Middleware\CheckAbilities::class,
'ability' => \Laravel\Sanctum\Http\Middleware\CheckForAnyAbility::class,
];
}
This is how my token is created:
public function update(Request $request, $id)
{
$validator = Validator::make($request->all(), [
'name' => 'required|string|max:255',
'email' => ['required', Rule::unique('users')->ignore($id)],
'has_token' => 'nullable|boolean',
'password' => $request->filled('password') ? 'required|min:8' : '',
'token_name' => [
'nullable',
'string',
Rule::requiredIf(function () use ($request) {
return $request->has_token === 1;
}),
],
]);
if ($validator->fails()) {
return response()->json(['errors' => $validator->errors()], 422);
}
try {
$user = User::find($id);
if ($request->email !== $user->email) {
return $this->changeEmail($request->email, $request->password, $id);
}
// Update fields
$user->name = $request->name;
$user->current_credits = $request->current_credits;
if ($request->filled('password')) {
$user->password = Hash::make($request->password);
}
$user->save();
$user = User::where('email', $request->email)->first();
if ($request->has_token === 1 && $request->filled('token_name')) {
$user->createToken($request->token_name, ['db:view', 'db:update', 'db:store']);
} elseif ($request->has_token === 0) {
$user->tokens()->delete();
}
} catch (Exception $e) {
return response()->json(['error' => $e->getMessage()], 500);
}
return response()->json(['success' => 'success'], 200);
}
I can see the token in the database, image attached: https://i.stack.imgur.com/az8vS.png
Thanks in advance!
via
Chebli Mohamed