vendredi 11 août 2023

Unable to communicate with Sanctum - I am getting a 503 error

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

Aucun commentaire:

Enregistrer un commentaire