dimanche 29 janvier 2017

How can I correctly put and retrieve a GenericUser object into and from the session in this "custom user provider" Laravel login?

I am not so into PHP and Laravel and I have the following problem, I came from Java.

I am following this tutorial to implement a custom user provider:

http://ift.tt/1pfYtX4

I am using Larave 5.3 version.

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.

To do this I have implemented the previous tutorial (and it seems to works) implementing this custom user provider class named UserProvider that implements the Laravel IlluminateUserProvider interface:

<?php

namespace App\Authentication;

use Illuminate\Auth\GenericUser;
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;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;

class UserProvider implements IlluminateUserProvider
{
    public function retrieveById($identifier)
    {
        // TODO: Implement retrieveById() method.
        \Log::info('retrieveById START');

        $user = \Session::get('loggedUser');

        //$user = Auth::user();

        return $user;

    }

    public function retrieveByToken($identifier, $token)
    {
        // TODO: Implement retrieveByToken() method.
        \Log::info('retrieveByToken START');
    }

    public function updateRememberToken(Authenticatable $user, $token)
    {
        // TODO: Implement updateRememberToken() method.
        \Log::info('updateRememberToken START');
    }

    public function retrieveByCredentials(array $credentials) {

        // TODO: Implement retrieveByCredentials() method.

        \Log::info('retrieveByCredentials START');
        \Log::info('INSERTED USER CREDENTIAL: '.$credentials['email'] . ' ' .$credentials['password']);

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

        $response = $client->get('http://localhost:8080/Extranet/login',
            [
                'auth' => [
                    'nobili.andrea@gmail.com',
                    'pswd'
                ]
            ]);

        $dettagliLogin = json_decode($response->getBody());

        \Log::info('response: '.(json_encode($dettagliLogin)));

        //$user = new User('Pippo', 'pippo@google.com', true);

        $attributes = array(
            'id' => 123,
            'username' => 'nobili.andrea@gmail.com',
            'password' => \Hash::make('SuperSecret'),
            'name' => 'Dummy User',
        );

        $user = new GenericUser($attributes);

        \Log::info('USER: '.(json_encode($user)));

        \Session::set('loggedUser', $user);

        return $user;


    }

    public function validateCredentials(Authenticatable $user, array $credentials)
    {
        // TODO: Implement validateCredentials() method.
        \Log::info('validateCredentials START');
        return true;
    }

}

So, doing in this way it seems to works fine but I have some doubts:

This is only a preliminary test so the returned data are mocked.

It works in this way:

1) When the user insert his credential in the login page (http://localhost:8000/login) it is called the retrieveByCredentials() method:

public function retrieveByCredentials(array $credentials) {

    // TODO: Implement retrieveByCredentials() method.

    \Log::info('retrieveByCredentials START');
    \Log::info('INSERTED USER CREDENTIAL: '.$credentials['email'] . ' ' .$credentials['password']);

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

    $response = $client->get('http://localhost:8080/Extranet/login',
        [
            'auth' => [
                'nobili.andrea@gmail.com',
                'pswd'
            ]
        ]);

    $dettagliLogin = json_decode($response->getBody());

    \Log::info('response: '.(json_encode($dettagliLogin)));

    //$user = new User('Pippo', 'pippo@google.com', true);

    $attributes = array(
        'id' => 123,
        'username' => 'nobili.andrea@gmail.com',
        'password' => \Hash::make('SuperSecret'),
        'name' => 'Dummy User',
    );

    $user = new GenericUser($attributes);

    \Log::info('USER: '.(json_encode($user)));

    \Session::set('loggedUser', $user);

    return $user;

}

that performs a web service call to obtain the user information related to this user. Then these credential are verified by the validateCredentials() method (at this time it returns true every time). Finnaly it returns a GenericUser objct containing the information of the logged user (at this time are mocked because is a test and I have not yet paresed the JSON reeturned by my web service) that is put into the session by this statment:

\Session::set('loggedUser', $user);

Then, when the verified logged user is redirected to the next page (after the success login) it seems to me that is called the retrieveById($identifier) method, this:

public function retrieveById($identifier)
{
    // TODO: Implement retrieveById() method.
    \Log::info('retrieveById START');

    $user = \Session::get('loggedUser');

    //$user = Auth::user();

    return $user;

}

that retrieve the logged user from the session so it can be used in the next view. It works fine, infact I correctly log into the next page and I can see the setted mocked Dummy User as logged user. From here also the log out function works fine.

But I am asking if put the GenericUser object into the section in the retrieveByCredentials(array $credentials) and then retrieve it into the retrieveById($identifier) is the neater solution.

Here I have posted a similar question: Can I put and retrieve the user information to and from session into a Laravel custom user provider?

And reading the obtained response it seems that the validated user is automatically putted inside the session but if I don't manually store and retrieve the user into and from the session by:

\Session::set('loggedUser', $user);

and:

$user = \Session::get('loggedUser');

in the previous 2 methods it doesn't works. Infact after the log in it come back to the login form page and not to the home page.

In the previous response it says to me about the Auth::user() method but I can't understand how exactly works and if I have to configure this SessionGuard in some way. What exactly is this SessionGuard? Have I to configure it to correctly use the session?

Anyway my original solution could be considered a good solution?



via Chebli Mohamed

Aucun commentaire:

Enregistrer un commentaire