Authentication¶
Authentication is an important part of the shop software. There are two ways of authenticate a user (normal customer or admin):
- Authentication by email address and password using the
UserAuthenticatorservice - Authentication by a JSON web token using the
JsonWebTokenAuthenticatorservice
UserAuthenticator service¶
The Gambio\Core\Auth\UserAuthenticator service is used in most cases, e.g. the login page or REST API.
Besides the authentication of a user, this services provides the functionality to change the password of a user,
or to generate a request key if the user has forgotten his password.
Authenticate a user¶
The UserAuthenticator provides a simple authentication method, which expects a user's email address and password.
The method returns a Gambio\Core\Auth\UserId object, which provides a userId method that returns the ID of
the authenticated user.
If the user can't be authenticated, a Gambio\Core\Auth\Exceptions\AuthenticationException exception will be thrown.
The following example shows how you could use this service:
namespace GXModules\<Vendor>\<Module>;
use Gambio\Core\Auth\UserAuthenticator;
use Gambio\Core\Auth\Exceptions\AuthenticationException;
/**
* Class SampleClass
* @package GXModules\<Vendor>\<Module>
*/
class SampleClass
{
/**
* @var UserAuthenticator
*/
private $authenticator;
/**
* SampleClass constructor.
*
* @param UserAuthenticator $authenticator
*/
public function __construct(UserAuthenticator $authenticator)
{
$this->authenticator = $authenticator;
}
/**
* @param string $email
* @param string $password
*
* @return int
*/
public function checkUserCredentials(string $email, string $password): int
{
try {
$userId = $this->authenticator->authenticate($email, $password);
return $userId->userId();
} catch (AuthenticationException $exception) {
return false;
}
}
}
Notice
This example expects you to use the Service Provider to register your classes to the Application Core. If your are using the legacy architecture, you need to fetch this service using the Legacy DI Container.
Work in progress - Update user password¶
As said, the service also provides the possibility to update a users' password.
The following example shows how you could use this service:
namespace GXModules\<Vendor>\<Module>;
use Gambio\Core\Auth\UserAuthenticator;
use Gambio\Core\Auth\UserId;
use Gambio\Core\Auth\Exceptions\UserNotFound;
/**
* Class SampleClass
* @package GXModules\<Vendor>\<Module>
*/
class SampleClass
{
/**
* @var UserAuthenticator
*/
private $authenticator;
/**
* SampleClass constructor.
*
* @param UserAuthenticator $authenticator
*/
public function __construct(UserAuthenticator $authenticator)
{
$this->authenticator = $authenticator;
}
/**
* @param int $userId
* @param string $newPassword
*
* @return bool
*/
public function updateUserCredentials(int $userId, string $newPassword): bool
{
try {
$this->authenticator->updateUserPassword($userId, $newPassword);
return true;
} catch (UserNotFound $exception) {
return false;
}
}
}
Notice
This example expects you to use the Service Provider to register your classes to the Application Core. If your are using the legacy architecture, you need to fetch this service using the Legacy DI Container.
Work in progress - Generate request key¶
If a user forgot his password, it's possible to create a request key to change the password.
The following example shows how you could use this service:
namespace GXModules\<Vendor>\<Module>;
use Gambio\Core\Auth\UserAuthenticator;
use Gambio\Core\Auth\UserId;
use Gambio\Core\Auth\Exceptions\UserNotFound;
/**
* Class SampleClass
* @package GXModules\<Vendor>\<Module>
*/
class SampleClass
{
/**
* @var UserAuthenticator
*/
private $authenticator;
/**
* SampleClass constructor.
*
* @param UserAuthenticator $authenticator
*/
public function __construct(UserAuthenticator $authenticator)
{
$this->authenticator = $authenticator;
}
/**
* @param int $userId
*
* @return string|null
*/
public function updateUserCredentials(int $userId): ?string
{
try {
return $this->authenticator->generateRequestKey($userId, $newPassword);
} catch (UserNotFound $exception) {
return null;
}
}
}
Notice
This example expects you to use the Service Provider to register your classes to the Application Core. If your are using the legacy architecture, you need to fetch this service using the Legacy DI Container.
Password hashes¶
Since the user's passwords are only available in the database as hashes, the validation of the passwords is based on
implementations of the Gambio\Core\Auth\HashStrategy interface, for which there are currently two implementations:
Gambio\Core\Auth\HashStrategies\Md5HashStrategycreates and validates password hashes using MD5Gambio\Core\Auth\HashStrategies\PhpNativeHashStrategycreates and validates password hashes using the PHP native functionspassword_hashandpassword_verify. This strategy is used primarly.
JsonWebTokenAuthenticator service¶
The JsonWebTokenAuthenticator provides a simple authenticate method, which expects a JSON web token. The method
returns a Gambio\Core\Auth\UserId object, which provides a userId method, that returns the ID of the
authenticated user.
If the user can't be authenticated, a Gambio\Core\Auth\Exceptions\AuthenticationException exception will be thrown.
The following example shows how you could use this service:
namespace GXModules\<Vendor>\<Module>;
use Gambio\Core\Auth\JsonWebTokenAuthenticator;
use Gambio\Core\Auth\Exceptions\AuthenticationException;
/**
* Class SampleClass
* @package GXModules\<Vendor>\<Module>
*/
class SampleClass
{
/**
* @var JsonWebTokenAuthenticator
*/
private $authenticator;
/**
* SampleClass constructor.
*
* @param JsonWebTokenAuthenticator $authenticator
*/
public function __construct(JsonWebTokenAuthenticator $authenticator)
{
$this->authenticator = $authenticator;
}
/**
* @param string $token
*
* @return int
*/
public function checkUserCredentials(string $token): int
{
try {
$userId = $this->authenticator->authenticate($token);
return $userId->userId();
} catch (AuthenticationException $exception) {
return false;
}
}
}
Notice
This example expects you to use the Service Provider to register your classes to the Application Core. If your are using the legacy architecture, you need to fetch this service using the Legacy DI Container.