mercredi 25 janvier 2017

Why I obtain this fatal error "Class 'App\Providers\AuthServiceProvider' not found" trying to implement my custom user provider in Laravel 5.3?

I am absolutly new in PHP and Laravel, I came from Java.

I am trying to follow this tutorial to implement a custom user provider:

http://ift.tt/1pfYtX4

I briefly expain what I need: my Laravel application is only a front end application, all the business logic, included the user authentication, is performed by a Java back end application that exposes REST web services.

Performing a call to:

http://localhost:8080/Extranet/login

and passing username and password as basic authentication I obtain a JSON response like this that represent the logged user:

{
  "userName": "Painkiller",
  "email": "painkiller@gmail.com",
  "enabled": true
}

So, in my Laravel application, I have to perform this call and then parse the previous returned JSON object to generate the authenticated object into the front end application session.

I think that the previous custom user provider is the neater and most natural solution to do it, but I am finding some difficulties and I have many doubts about how do it in my project.

I am using Larave 5.3 version.

I have done the following steps (following the previous tutorial and trying to adapt it to my needs):

1) Stage 1: Register your custom user provider:

I have created my service provider in which I have register mycustom authentication user provider (the custom component used to perform my custom login via web service).

So into the app directory of my Laravel project I have created the Authentication subdirectory and here I have put this AuthServiceProvider that extends ServiceProvider:

<?php
namespace App\Authentication;

use Auth;
use App\Authentication\UserProvider;
use Illuminate\Support\ServiceProvider;

class AuthServiceProvider extends ServiceProvider {
    /**
     * Perform post-registration booting of services.
     *
     * @return void
     */
    public function boot()
    {
        Auth::provider('our_provider', function ($app, array $config) {
            return new UserProvider();
        });
    }

    /**
     * Register bindings in the container.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

This simply registers your user provider/driver, making it usable in the config/auth.php file via the our_provider key.

FIRST DOUBT: passing the mouse on the:

use Auth;

it result Undefined class Auth, why? It seems to me that it is not used in the previous code, maybe a tutorial inclusion error or am I missing something?

Then I registerd this service into my config/app.php file:

This is the providers section of this file:

'providers' => [

    /*
     * Laravel Framework Service Providers...
     */
    Illuminate\Auth\AuthServiceProvider::class,
    Illuminate\Broadcasting\BroadcastServiceProvider::class,
    Illuminate\Bus\BusServiceProvider::class,
    Illuminate\Cache\CacheServiceProvider::class,
    Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class,
    Illuminate\Cookie\CookieServiceProvider::class,
    Illuminate\Database\DatabaseServiceProvider::class,
    Illuminate\Encryption\EncryptionServiceProvider::class,
    Illuminate\Filesystem\FilesystemServiceProvider::class,
    Illuminate\Foundation\Providers\FoundationServiceProvider::class,
    Illuminate\Hashing\HashServiceProvider::class,
    Illuminate\Mail\MailServiceProvider::class,
    Illuminate\Notifications\NotificationServiceProvider::class,
    Illuminate\Pagination\PaginationServiceProvider::class,
    Illuminate\Pipeline\PipelineServiceProvider::class,
    Illuminate\Queue\QueueServiceProvider::class,
    Illuminate\Redis\RedisServiceProvider::class,
    Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
    Illuminate\Session\SessionServiceProvider::class,
    Illuminate\Translation\TranslationServiceProvider::class,
    Illuminate\Validation\ValidationServiceProvider::class,
    Illuminate\View\ViewServiceProvider::class,

    /*
     * Package Service Providers...
     */

    //

    /*
     * Application Service Providers...
     */
    App\Providers\AppServiceProvider::class,
    App\Providers\AuthServiceProvider::class,
    // App\Providers\BroadcastServiceProvider::class,
    App\Providers\EventServiceProvider::class,
    App\Providers\RouteServiceProvider::class,
    App\Authentication\AuthServiceProvider::class,

],

as you can see this array contains my App\Authentication\AuthServiceProvider::class, representing the previous ServiceProvider. Is it correct?

2: Stage 2: Update config to use new driver:

I tell to my Laravel application to use the previous user provider, so I go into the config/auth.php configuration file and I set my provider:

'providers' => [
    'users' => [
        'driver' => 'our_provider',
    ],
],

For the sake of completeness I post the entire content of my config/auth.php so you can see if there are some other error:

<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Authentication Defaults
    |--------------------------------------------------------------------------
    |
    | This option controls the default authentication "guard" and password
    | reset options for your application. You may change these defaults
    | as required, but they're a perfect start for most applications.
    |
    */

    'defaults' => [
        'guard' => 'web',
        'passwords' => 'users',
    ],

    /*
    |--------------------------------------------------------------------------
    | Authentication Guards
    |--------------------------------------------------------------------------
    |
    | Next, you may define every authentication guard for your application.
    | Of course, a great default configuration has been defined for you
    | here which uses session storage and the Eloquent user provider.
    |
    | All authentication drivers have a user provider. This defines how the
    | users are actually retrieved out of your database or other storage
    | mechanisms used by this application to persist your user's data.
    |
    | Supported: "session", "token"
    |
    */

    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],

        'api' => [
            'driver' => 'token',
            'provider' => 'users',
        ],
    ],

    /*
    |--------------------------------------------------------------------------
    | User Providers
    |--------------------------------------------------------------------------
    |
    | All authentication drivers have a user provider. This defines how the
    | users are actually retrieved out of your database or other storage
    | mechanisms used by this application to persist your user's data.
    |
    | If you have multiple user tables or models you may configure multiple
    | sources which represent each model / table. These sources may then
    | be assigned to any extra authentication guards you have defined.
    |
    | Supported: "database", "eloquent"
    |
    */

    /*
    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\User::class,
        ],
    */

    'providers' => [
        'users' => [
            'driver' => 'our_provider',
        ],


        // 'users' => [
        //     'driver' => 'database',
        //     'table' => 'users',
        // ],
    ],

    /*
    |--------------------------------------------------------------------------
    | Resetting Passwords
    |--------------------------------------------------------------------------
    |
    | You may specify multiple password reset configurations if you have more
    | than one user table or model in the application and you want to have
    | separate password reset settings based on the specific user types.
    |
    | The expire time is the number of minutes that the reset token should be
    | considered valid. This security feature keeps tokens short-lived so
    | they have less time to be guessed. You may change this as needed.
    |
    */

    'passwords' => [
        'users' => [
            'provider' => 'users',
            'table' => 'password_resets',
            'expire' => 60,
        ],
    ],

];

3) Stage 3: Create a user class:

I think that this is something like a model object that will contains the data received from my web service (if the user can log into the system).

So if I am not missing something it have to contains a structure like this (username, email, ebabled fields):

{
  "userName": "Painkiller",
  "email": "painkiller@gmail.com",
  "enabled": true
}

According to the tutorial this user class must implement the Laravel Illuminate\Contracts\Auth\Authenticatable interface.

So into the /app/Authentication class (the same one that contains the previous AuthServiceProvicer class) I put this User class implementing the Authenticatable interface:

<?php

namespace App\Authentication;

use Illuminate\Contracts\Auth\Authenticatable;

class User implements Authenticatable {
    /**
     * @return string
     */
    public function getAuthIdentifierName()
    {
        // Return the name of unique identifier for the user (e.g. "id")
    }

    /**
     * @return mixed
     */
    public function getAuthIdentifier()
    {
        // Return the unique identifier for the user (e.g. their ID, 123)
    }

    /**
     * @return string
     */
    public function getAuthPassword()
    {
        // Returns the (hashed) password for the user
    }

    /**
     * @return string
     */
    public function getRememberToken()
    {
        // Return the token used for the "remember me" functionality
    }

    /**
     * @param  string $value
     * @return void
     */
    public function setRememberToken($value)
    {
        // Store a new token user for the "remember me" functionality
    }

    /**
     * @return string
     */
    public function getRememberTokenName()
    {
        // Return the name of the column / attribute used to store the "remember me" token
    }
}

DOUBT: The tutorial example put in this class only the stubbded methods, I have no token and I think that I only want to retrieve te previous username, email, ebabled fields. So I think that this class is incomplete. Whate have I exactly to do? Create these 3 fields (that represent the user information returned by my web service) and the related getter methods? Is it or am I missing something?

4) Stage 4: Create a UserProvider class:

In stage 1, I have a callback function which returned an instance of App\Authentication\UserProvider, this class is used to retrieve instances of our users App\Authentication\User.

This class have to implement the Illuminate\Contracts\Auth\UserProvider interface. It seems to me that the method that have to be implemented will contain the logic to retrieve my user information (so in my specific case where I have to put my web service call).

So in the same app/Authentication directory I have put this UserProvider implementing the Illuminate\Contracts\Auth\UserProvider interface, this is my code:

namespace App\Authentication;

use Illuminate\Contracts\Auth\Authenticatable; use Illuminate\Contracts\Auth\UserProvider as IlluminateUserProvider; use GuzzleHttp\Client; use function GuzzleHttp\json_encode; use function GuzzleHttp\json_decode;

class UserProvider implements IlluminateUserProvider { public function retrieveById($identifier) { // TODO: Implement retrieveById() method. }

public function retrieveByToken($identifier, $token)
{
    // TODO: Implement retrieveByToken() method.
}

public function updateRememberToken(Authenticatable $user, $token)
{
    // TODO: Implement updateRememberToken() method.
}

public function retrieveByCredentials(array $credentials)
{
    // TODO: Implement retrieveByCredentials() method.

    $client = new Client(); //GuzzleHttp\Client

    $response = $client->post('http://localhost:8080/Extranet/login',
        [
            'auth' => [
                'Painkiller',
                'pswd'
            ]
        ]);


}

public function validateCredentials(Authenticatable $user, array $credentials)
{
    // TODO: Implement validateCredentials() method.
}

}

So I think that I have to put my webservice call in this method retrieveByCredentials(), this one:

public function retrieveByCredentials(array $credentials)
{
    // TODO: Implement retrieveByCredentials() method.

    $client = new Client(); //GuzzleHttp\Client

    $response = $client->post('http://localhost:8080/Extranet/login',
        [
            'auth' => [
                'Painkiller',
                'pswd'
            ]
        ]);


}

For semplicity, at this time I have hard coded the credential of an existing user returned by the web service doing performing an http request, so for any credential inserted by the user in the login form will always retrieve this user (I want to do a test...then I will integrate with the inserted credential).

Ok, this is the logic that I have understand following this tutorial, is it correct or am I missing something?

Then I start my Laravel project by the statment php artisan serve but I am obtaining the following error message:

Andrea@Andrea-PC MINGW64 ~/Documents/Betrivius/WorkSpace/betriviusExtranet (master)
$ php artisan serve
PHP Fatal error:  Class 'App\Providers\AuthServiceProvider' not found in C:\Users\Andrea\Documents\Betrivius\WorkSpace\betriviusExtranet\vendor\laravel\framework\src\Illuminate\Foundation\ProviderRepository.php on line 146


  [Symfony\Component\Debug\Exception\FatalErrorException]
  Class 'App\Providers\AuthServiceProvider' not found

Why? What is wrong? What am I missing? How can I fix this issue?



via Chebli Mohamed

Aucun commentaire:

Enregistrer un commentaire