0

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
    }
}
2
  • stackoverflow.com/questions/61060183/… - DiactorosFactory was removed in psr-http-message-bridge v2.0 Commented Sep 12, 2023 at 18:31
  • Yes, which is why in the changed file I removed DiactorosFactory and am using PsrHttpFactory instead. However, after then changes all connections aside from getting a token result in "Unauthenticated" Commented Sep 12, 2023 at 19:23

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.