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
UserAuthenticator
service - Authentication by a JSON web token using the
JsonWebTokenAuthenticator
service
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\Md5HashStrategy
creates and validates password hashes using MD5Gambio\Core\Auth\HashStrategies\PhpNativeHashStrategy
creates and validates password hashes using the PHP native functionspassword_hash
andpassword_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.