Laravel API calls no longer work after upgrading to Laravel 8

81 Views Asked by At

I'm upgrading an old Laravel app to Laravel 8. Everything went fine with the upgrade except for being able to connect through the API. When I do try, I get a crash message Class 'Symfony\Bridge\PsrHttpMessage\Factory\DiactorosFactory' not found. I followed a short guide (https://symfony.com/doc/current/components/psr7.html#usage) to use PSR-7 instead, but after that all API calls came back as simple Unauthenticated, even though I'm using the same credentials as before. I'm able to use curl to get a new access token with a call to /oauth/token, but even using that new token tells me it's unauthenticated when I make any other call.

The thing is, the middleware isn't a file that I coded. It seems to be a generic middleware for API calls and I don't really understand what it's doing. Is there a default API middleware, dealing with access tokens and all that, that I should be using for Laravel 8? Or are there other changes I should be making to the file to make it work again?

The file in question, app/Http/Middleware/MyCheckClientCredentials, which worked fine in Laravel 6 and 7, is

<?php

namespace App\Http\Middleware;


use Closure;
use League\OAuth2\Server\ResourceServer;
use Illuminate\Auth\AuthenticationException;
use Laravel\Passport\Exceptions\MissingScopeException;
use League\OAuth2\Server\Exception\OAuthServerException;
use Symfony\Bridge\PsrHttpMessage\Factory\DiactorosFactory;

class MyCheckClientCredentials
{
    /**
     * The Resource Server instance.
     *
     * @var \League\OAuth2\Server\ResourceServer
     */
    private $server;

    /**
     * Create a new middleware instance.
     *
     * @param  \League\OAuth2\Server\ResourceServer  $server
     * @return void
     */
    public function __construct(ResourceServer $server)
    {
        $this->server = $server;
    }

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @param  mixed  ...$scopes
     * @return mixed
     * @throws \Illuminate\Auth\AuthenticationException
     */
    public function handle($request, Closure $next, ...$scopes)
    {
        $psr = (new DiactorosFactory)->createRequest($request);

        try {
            $psr = $this->server->validateAuthenticatedRequest($psr);
            $request['oauth_client_id'] = $psr->getAttribute('oauth_client_id');
        } catch (OAuthServerException $e) {
            throw new AuthenticationException;
        }

        $this->validateScopes($psr, $scopes);

        return $next($request);
    }

    /**
     * Validate the scopes on the incoming request.
     *
     * @param  \Psr\Http\Message\ResponseInterface $psr
     * @param  array  $scopes
     * @return void
     * @throws \Laravel\Passport\Exceptions\MissingScopeException
     */
    protected function validateScopes($psr, $scopes)
    {
        if (in_array('*', $tokenScopes = $psr->getAttribute('oauth_scopes'))) {
            return;
        }

        foreach ($scopes as $scope) {
            if (! in_array($scope, $tokenScopes)) {
                throw new MissingScopeException($scope);
            }
        }
    }
}

The updated middleware that always says Unauthenticated but at least doesn't crash:

<?php

namespace App\Http\Middleware;


use Closure;
use League\OAuth2\Server\ResourceServer;
use Illuminate\Auth\AuthenticationException;
use Laravel\Passport\Exceptions\MissingScopeException;
use League\OAuth2\Server\Exception\OAuthServerException;
//use Symfony\Bridge\PsrHttpMessage\Factory\DiactorosFactory;
use Nyholm\Psr7\Factory\Psr17Factory;
use Symfony\Bridge\PsrHttpMessage\Factory\PsrHttpFactory;
use Symfony\Component\HttpFoundation\Request;

class MyCheckClientCredentials
{
    /**
     * The Resource Server instance.
     *
     * @var \League\OAuth2\Server\ResourceServer
     */
    private $server;

    /**
     * Create a new middleware instance.
     *
     * @param  \League\OAuth2\Server\ResourceServer  $server
     * @return void
     */
    public function __construct(ResourceServer $server)
    {
        $this->server = $server;
    }

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @param  mixed  ...$scopes
     * @return mixed
     * @throws \Illuminate\Auth\AuthenticationException
     */
    public function handle($request, Closure $next, ...$scopes)
    {
        //$psr = (new DiactorosFactory)->createRequest($request);
        $symfonyRequest = new Request([], [], [], [], [], ['HTTP_HOST' => 'toi.development.lib.utah.edu'], 'Content');
        // The HTTP_HOST server key must be set to avoid an unexpected error

        $psr17Factory = new Psr17Factory();
        $psrHttpFactory = new PsrHttpFactory($psr17Factory, $psr17Factory, $psr17Factory, $psr17Factory);
        $psr = $psrHttpFactory->createRequest($symfonyRequest);

        try {
            $psr = $this->server->validateAuthenticatedRequest($psr);
            $request['oauth_client_id'] = $psr->getAttribute('oauth_client_id');
        } catch (OAuthServerException $e) {
            throw new AuthenticationException;
        }

        $this->validateScopes($psr, $scopes);

        return $next($request);
    }

    /**
     * Validate the scopes on the incoming request.
     *
     * @param  \Psr\Http\Message\ResponseInterface $psr
     * @param  array  $scopes
     * @return void
     * @throws \Laravel\Passport\Exceptions\MissingScopeException
     */
    protected function validateScopes($psr, $scopes)
    {
        if (in_array('*', $tokenScopes = $psr->getAttribute('oauth_scopes'))) {
            return;
        }

        foreach ($scopes as $scope) {
            if (! in_array($scope, $tokenScopes)) {
                throw new MissingScopeException($scope);
            }
        }
    }
}

Composer file:

{
    "name": "laravel/laravel",
    "description": "The Laravel Framework.",
    "keywords": ["framework", "laravel"],
    "license": "MIT",
    "type": "project",
    "require": {
        "php": ">=7.1",
        "doctrine/dbal": "^2.5",
        "fideloper/proxy": "~4.0",
        "laravel/framework": "^8.0",
        "laravel/helpers": "^1.4",
        "laravel/passport": "^10.0",
        "laravel/tinker": "~2.0",
        "lcobucci/jwt": "^4.0",
        "subfission/cas": "dev-master",
        "symfony/psr-http-message-bridge": "^2.0",
        "nyholm/psr7": "^1.5",
        "zendframework/zend-diactoros": "2.2.1",
        "guzzlehttp/guzzle": "^7.0.1",
        "laravel/ui": "^3.0"

    },
    "require-dev": {
        "facade/ignition": "^2.3.6",
        "filp/whoops": "~2.0",
        "fzaninotto/faker": "~1.4",
        "mockery/mockery": "0.9.*",
        "nunomaduro/collision": "^5.0",
        "phpunit/phpunit": "^9.0"
    },
    "autoload": {
        "psr-4": {
            "App\\": "app/",
            "Database\\Factories\\": "database/factories/",
            "Database\\Seeders\\": "database/seeders/"
        },
        "files": [
            "app/Functions/helper_functions.php"
        ]
    },
    "autoload-dev": {
        "psr-4": {
            "Tests\\": "tests/"
        }
    },
    "extra": {
        "laravel": {
            "dont-discover": [
            ]
        }
    },
    "scripts": {
        "post-root-package-install": [
            "@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
        ],
        "post-create-project-cmd": [
            "@php artisan key:generate"
        ],
        "post-autoload-dump": [
            "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
            "@php artisan package:discover"
        ]
    },
    "config": {
        "preferred-install": "dist",
        "sort-packages": true,
        "optimize-autoloader": true
    }
}
0

There are 0 best solutions below