The Account provides common interface for user authentication.
composer require webiik/accountThe following example expects you have already written your account implementation and you use email and password for user authentication.
$account = new \Webiik\Account\Account();
// Add your account implementation
$account->addAccount('YourAccount', function () {
return new \Webiik\Service\YourAccount());
});
// Use one of your account implementations
$account->useAccount('YourAccount');
// Try authenticate a user
try {
$user = $this->account->auth([
'email' => 'kitty@webiik.com',
'password' => 'meow!'
]);
echo 'User ID: ' . $user->getId() . '<br/>';
echo 'User status: ' . $user->getStatus() . '<br/>';
echo 'User role: ' . $user->getRole() . '<br/>';
if ($user->hasRole('admin')) {
// Do something...
}
} catch (AccountException $e) {
echo $e->getMessage() . '<br/>';
print_r($e->getValidationResult());
}addAccount(string $name, callable $accountFactory): voidaddAccount() adds an implementation of account.
$account->addAccount('YourAccount', function () {
return new \Webiik\Service\YourAccount());
});useAccount(string $name): voiduseAccount() sets account to be used when calling custom account related methods.
$account->useAccount('YourAccount');setNamespace(string $namespace): voidsetNamespace() sets authentication namespace. It allows you to use separate authentication for different parts of your application. If you don't set any namespace, it means user belongs to default namespace.
// Set namespace to 'en'
$account->setNamespace('en');
// Let's say, user 'kitty@webiik.com' is authenticated in
// namespace 'es', so the following authentication fails.
try {
$user = $this->account->auth([
'email' => 'kitty@webiik.com',
'password' => 'meow!'
]);
} catch (AccountException $e) {
echo $e->getMessage(); // e.g. Account does not exist.
}To write your account implementation you have to extend from abstract class AccountBase and write your own implementation of methods auth, signup, update, disable, delete, createToken, activate and resetPassword. Don't forget to incorporate authentication namespace to each method. Read below intended function of each mentioned method and adapt your implementation to it.
auth(array $credentials): Userauth() authenticates a user with credentials. On success returns User, on error throws AccountException. Possible exception status codes: METHOD_IS_NOT_IMPLEMENTED, INVALID_CREDENTIAL, INVALID_PASSWORD, ACCOUNT_DOES_NOT_EXIST, ACCOUNT_IS_NOT_ACTIVATED, ACCOUNT_IS_BANNED, ACCOUNT_IS_DISABLED, FAILURE
try {
$user = $this->account->auth([
'email' => 'kitty@webiik.com',
'password' => 'meow!'
]);
} catch (AccountException $e) {
echo $e->getMessage();
}To compare passwords, always use secure method
verifyPassword(string $password, string $hash): boolprovided by AccountBase.
reAuth(string $uid): UserreAuth() re-authenticates a user by unique user identifier uid. On success returns User, on error throws AccountException. Possible exception status codes: METHOD_IS_NOT_IMPLEMENTED, ACCOUNT_DOES_NOT_EXIST, ACCOUNT_IS_NOT_ACTIVATED, ACCOUNT_IS_BANNED, ACCOUNT_IS_DISABLED, FAILURE
try {
$user = $this->account->reAuth('d4rjke8');
} catch (AccountException $e) {
echo $e->getMessage();
}signup(array $credentials): Usersignup() signs up a user with credentials. On success returns User, on error throws AccountException. Possible exception status codes: METHOD_IS_NOT_IMPLEMENTED, INVALID_CREDENTIAL, ACCOUNT_ALREADY_EXISTS, FAILURE
try {
$user = $this->account->signup([
'email' => 'kitty@webiik.com',
'password' => 'meow!'
]);
} catch (AccountException $e) {
echo $e->getMessage();
}Never store passwords in plain text. AccountBase provides you secure method to hash passwords
hashPassword(string $password): string.
update(int $uid, array $data): Userupdate() updates data on account with id uid. On success returns User, on error throws AccountException. Possible exception status codes: METHOD_IS_NOT_IMPLEMENTED, ACCOUNT_DOES_NOT_EXIST, INVALID_KEY, FAILURE
try {
$user = $this->account->update(1, [
'email' => 'nyan@webiik.com',
]);
} catch (AccountException $e) {
echo $e->getMessage();
}disable(int $uid, int $reason, array $data = []): Userdisable() sets account status to ACCOUNT_IS_DISABLED or ACCOUNT_IS_BANNED on account with id uid. On success returns User, on error throws AccountException. Possible exception status codes: METHOD_IS_NOT_IMPLEMENTED, ACCOUNT_DOES_NOT_EXIST, FAILURE
try {
$user = $this->account->disable(1, \Webiik\Account\AccountBase::ACCOUNT_IS_BANNED);
} catch (AccountException $e) {
echo $e->getMessage();
}delete(int $uid, array $data = []): Userdelete() deletes an account with id uid. On success returns User, on error throws AccountException. Possible exception status codes: METHOD_IS_NOT_IMPLEMENTED, ACCOUNT_DOES_NOT_EXIST, FAILURE
try {
$user = $this->account->delete([
'uid' => 1,
]);
} catch (AccountException $e) {
echo $e->getMessage();
}createToken(): stringcreateToken() creates and returns time limited security token. On error throws AccountException. Possible exception status codes: METHOD_IS_NOT_IMPLEMENTED, FAILURE
try {
$token = $this->account->createToken();
// Send token to user, so he can perform an action...
} catch (AccountException $e) {
echo $e->getMessage();
}activate(string $token): Useractivate() activates an account by valid token. On success returns User, on error throws AccountException. Possible exception status codes: METHOD_IS_NOT_IMPLEMENTED, INVALID_TOKEN, FAILURE
try {
$user = $this->account->activate($token);
} catch (AccountException $e) {
echo $e->getMessage();
}resetPassword(string $token, string $password): UserresetPassword() updates account password by valid token. On success returns User, on error throws AccountException. Possible exception status codes: METHOD_IS_NOT_IMPLEMENTED, INVALID_TOKEN, FAILURE
try {
$user = $this->account->resetPassword($token, 'new-password');
} catch (AccountException $e) {
echo $e->getMessage();
}Never store passwords in plain text. AccountBase provides you secure method to hash passwords
hashPassword(string $password): string.
User is an object returned by several Account methods. User provides handy methods to work with authenticated user.
__construct(int $status, $id, string $role = '', array $info = [])__construct() creates User object.
Parameters
- status user account status. Usual status codes are: ACCOUNT_IS_OK and ACCOUNT_IS_NOT_ACTIVATED
- id unique user account id.
- role (optional) user role.
- info (optional) additional user account info.
$user = new User(self::ACCOUNT_IS_OK, 1, 'user');getId()getId() returns unique user account id.
$uid = $user->getId();getRole(): stringgetRole() returns user role.
$role = $user->getRole();hasRole(string $role): boolhasRole() checks if user has given role.
if ($user->hasRole('user') {
// Do something...
}getInfo(): arraygetInfo() returns additional user account info.
$info = $user->getInfo();needsActivation(): boolneedsActivation() checks if user account requires activation.
if ($user->needsActivation()) {
// Send activation to user email
}AccountException has to be thrown by all implemented account methods. Unlike standard Exception, AccountException has one extra parameter validationResult. This parameter is intended to store invalid credentials in the following format e.g. ['email' => ['Invalid email'], 'password' => ['Password is too short.']]
__construct($message = '', $code = 0, \Throwable $previous = null, array $validationResult = [])__construct() creates AccountException object.
throw new AccountException(self::MSG_INVALID_CREDENTIAL, self::INVALID_CREDENTIAL, null, ['email' => ['Invalid email'], 'password' => ['Password is too short.']]);getValidationResult(): arraygetValidationResult() returns invalid credentials.
try {
$user = $this->account->auth([
'email' => 'kitty@webiik.com',
'password' => 'meow!'
]);
} catch (AccountException $e) {
print_r($e->getValidationResult()); // e.g. ['email' => ['Invalid email'], 'password' => ['Password is too short.']]
}