vendredi 27 janvier 2017

Why am I obtaining this "These credentials do not match our records" message after a Custom User Providers authentication in Larvel?

I am pretty new in PHP and in Laravel.

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.

I have implemented all the 4 steps of the previous tutorial and I think that I have correctly replaced the user provider with my custom user provider that perform the web service call, this is my code:

It is not yet complete but it seems to works fine because submitting the Laravel login form of the http://localhost:8000/login page it enter into the retrieveByCredentials(array $credentials) method and the call to my REST web service is correctly performed.

At this time I am not using the inserted credential but I am mocking it only because I am lazy and I don't want to insert username and password in the login form every time that I do a test...

Reading also this official tutorial:

http://ift.tt/2jpH12I

it says that:

The retrieveByCredentials method receives the array of credentials passed to the Auth::attempt method when attempting to sign into an application. The method should then "query" the underlying persistent storage for the user matching those credentials. Typically, this method will run a query with a "where" condition on $credentials['username']. The method should then return an implementation of Authenticatable. This method should not attempt to do any password validation or authentication.

The validateCredentials method should compare the given $user with the $credentials to authenticate the user. For example, this method should probably use Hash::check to compare the value of $user->getAuthPassword() to the value of $credentials['password']. This method should return true or false indicating on whether the password is valid.

So, for simplicity the retrieveByCredentials() method returns a mocked User object (that implements the Authenticatable interface).

This is my code:

<?php

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

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

    }

    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);

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

        return $user;


    }

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

}

an this is the code of the returned User object (as you can see it contains the information obtained by the JSON from my web service):

<?php

namespace App\Authentication;

use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Support\Facades\Log;

class User implements Authenticatable {

    private $username;
    private $email;
    private $enabled;

    /**
     * User constructor.
     * @param $username
     * @param $email
     * @param $enabled
     */
    public function __construct($username, $email, $enabled)
    {
        $this->username = $username;
        $this->email = $email;
        $this->enabled = $enabled;
    }


    /**
     * @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
    }

    /**
     * @return mixed
     */
    public function getUsername()
    {
        return $this->username;
    }

    /**
     * @param mixed $username
     */
    public function setUsername($username)
    {
        $this->username = $username;
    }

    /**
     * @return mixed
     */
    public function getEmail()
    {
        return $this->email;
    }

    /**
     * @param mixed $email
     */
    public function setEmail($email)
    {
        $this->email = $email;
    }

    /**
     * @return mixed
     */
    public function getEnabled()
    {
        return $this->enabled;
    }

    /**
     * @param mixed $enabled
     */
    public function setEnabled($enabled)
    {
        $this->enabled = $enabled;
    }

}

So my retrieveByCredentials() method returns this User instance containing the mocked user information but I have the following problem:

after the login form submission, the retrieveByCredentials() is executed and the User instance is returned but I don't access to the index page and I see this error message: These credentials do not match our records.

enter image description here

From what I have understand this error message should be referred the Laravel standard authentication (on the DB), but I am absolutly not sure about this assertion.

How is it possible? I am creating a custom user provider in which my retrieveByCredentials() implements my custom logic.

What is wrong? What am I missing? How can I try to fix this issue and obtain the access after my Custom User Providers login?



via Chebli Mohamed

Aucun commentaire:

Enregistrer un commentaire