I am pretty new in PHP and in Laravel.
I am following this tutorial to implement a custom user provider:
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:
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.
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