Authsum is a simple authentication package written in PHP which allows to create simple and extensible authentication logic.
Install the Authsum package via Composer:
$ composer require rougin/authsumPrior in using Authsum, a data source must be defined first (e.g., BasicSource):
// index.phpuseRougin\Authsum\Source\BasicSource;
// ...$username = 'admin';
$password = /** ... */;
// Check if the provided username and password data ---// matched from the given payload (e.g., $_POST) ------$source = newBasicSource($username, $password);
// ----------------------------------------------------// ...Once the source is defined, use the Authsum class to perform the validation logic:
// index.phpuseRougin\Authsum\Authsum;
// ...$auth = newAuthsum($source);
if ($auth->isValid($_POST))
{
/** @var \Acme\Models\User */$user = $auth->getResult()->getField('user');
echo'Welcome ' . $user->getName() . '!';
}
else
{
echo'Invalid credentials!';
}Authsum also provides simple extensibility utilities to be able to fit in from various use-cases.
The Authsum class can also be extended to provide methods if the validation logic passed or failed:
namespaceAcme;
useAcme\Depots\AuditDepot;
useAcme\Errors\NoAccount;
useRougin\Authsum\Authsum;
useRougin\Authsum\Error;
useRougin\Authsum\Result;
class TestAuth extends Authsum
{
protected$audit;
publicfunction__construct(AuditDepot$audit)
{
$this->audit = $audit;
}
/** * Executes if the validation failed. * * @param \Rougin\Authsum\Error $error * * @return void */protectedfunctionfailed(Error$error)
{
thrownewNoAccount($error->getText());
}
/** * Executes if the validation passed. * * @param \Rougin\Authsum\Result $data * * @return void */protectedfunctionpassed(Result$data)
{
/** @var string */$user = $data->getField('name');
$this->audit->userLoggedIn($user);
}
}Alternatively, the Authsum class can also get the error or the result after validation using getError() and getResult() respectively:
// index.phpuseRougin\Authsum\Authsum;
// ...$auth = newAuthsum($source);
if ($auth->isValid($_POST))
{
$result = $auth->getResult();
/** @var string */$name = $result->getField('name');
echo'Welcome ' . $name . '!';
}
else
{
$error = $auth->getError();
echo'Error: ' . $auth->getText();
}Note
An UnexpectedValueException will be thrown if trying to access an empty output (e.g., trying to access getResult() after the failed validation).
By default, the Authsum class can check the email as its username and password for the password from the payload (e.g., $_POST). If this is not the case, kindly update the specified fields using setUsernameField or setPasswordField:
// index.php// ...$auth->setUsernameField('username');
$auth->setPasswordField('password');
// ...Note
The specified fields will be used by the Authsum class if they are required by the specified source (e.g., BasicSource, PdoSource).
Sources in Authsum are PHP classes that provide user data. They can be used for checking the specified username and password fields against its data source:
// index.phpuseRougin\Authsum\Authsum;
useRougin\Authsum\Source\BasicSource;
// ...// Initialize the source... --------------------$username = 'admin';
$password = /** ... */;
$source = newBasicSource($username, $password);
// ---------------------------------------------// ...then pass it to Authsum ---$auth = newAuthsum($source);
// ------------------------------// The source will be used to check if ---// the provided payload matches in the ---// given payload ($_POST) from its source$valid = $auth->isValid($_POST);
// ---------------------------------------// ...Besides from BasicSource, another available source that can be used is PdoSource which uses PDO to interact with a database:
// index.phpuseRougin\Authsum\Source\PdoSource;
// ...// Create a PDO instance... --------------$dsn = 'mysql:host=localhost;dbname=demo';
$pdo = newPDO($dsn, 'root', /** ... */);
// ---------------------------------------// ...then pass it to the PdoSource ---$source = newPdoSource($pdo);
// ------------------------------------// ...The setTableName method can also be used to specify its database table name:
// index.phpuseRougin\Authsum\Source\PdoSource;
// ...$source = newPdoSource($pdo);
$source->setTableName('users');
// ...Note
If the setTableName is not specified, it always refer to the users table.
When using PdoSource, the value in the password field will be assumed as a hash (e.g., $2y$10...). If this is not the case, kindly add the withoutHash method:
// index.phpuseRougin\Authsum\Source\PdoSource;
// ...$source = newPdoSource($pdo);
$source->withoutHash();
// ...Doing this will make a strict comparison of the provided password against the result from the database.
The JwtSource class is a special class that checks a user's authentication using JSON Web Token:
// index.phpuseRougin\Authsum\Source\JwtSource;
// .../** @var \Rougin\Authsum\Source\JwtParserInterface */$parser = /** ... */;
$source = newJwtSource($parser);From the example above, initializing JwtSource requires a JwtParserInterface for parsing the JSON web tokens from payload:
namespaceRougin\Authsum\Source;
interface JwtParserInterface
{
/** * Parses the token string. * * @param string $token * * @return array<string, mixed> */publicfunctionparse($token);
}If JwtSource is used as a source, the token field must be updated also from the Authsum class based on the query parameter or parsed body where the token exists:
// index.phpuseRougin\Authsum\Authsum;
useRougin\Authsum\Source\JwtSource;
// ...$source = newJwtSource($parser);
// Search "token" property from the payload ---$source->setTokenField('token');
// --------------------------------------------$auth = newAuthsum($source);Note
If setTokenField is not specified, its default value is token.
Then use the setUsernameField to specify the field to be compared against the parsed data from the JSON web token:
// index.phpuseRougin\Authsum\Authsum;
// ...$auth = newAuthsum($source);
// ...$auth->setUsernameField('email');
// The $_POST data should contains the ---// "token" field and the "email" field ---$valid = $auth->isValid($_POST);
// ---------------------------------------To create a custom source, kindly use the SourceInterface for its implementation:
namespaceRougin\Authsum\Source;
interface SourceInterface
{
/** * Returns the error after validation. * * @return \Rougin\Authsum\Error */publicfunctiongetError();
/** * Returns the result after validation. * * @return \Rougin\Authsum\Result */publicfunctiongetResult();
/** * Checks if it exists from the source. * * @return boolean */publicfunctionisValid();
}If the custom source requires an username field, kindly add the WithUsername interface:
namespaceRougin\Authsum\Source;
interface WithUsername
{
/** * Sets the username field. * * @param string $username * * @return self */publicfunctionsetUsernameField($username);
/** * Sets the username. * * @param string $username * * @return self */publicfunctionsetUsernameValue($username);
}The WithPassword interface can be also added if the custom source requires a password to be defined:
namespaceRougin\Authsum\Source;
interface WithPassword
{
/** * Sets the password field. * * @param string $password * * @return self */publicfunctionsetPasswordField($password);
/** * Sets the password value. * * @param string $password * * @return self */publicfunctionsetPasswordValue($password);
}Some custom sources may require to use the provided payload instead of username and password fields (e.g., JwtSource). With this, kindly use the WithPayload interface:
namespaceRougin\Authsum\Source;
interface WithPayload
{
/** * Sets the prepared payload. * * @param array<string, string> $payload * * @return self */publicfunctionsetPayload($payload);
}Please see CHANGELOG for more recent changes and latest updates.
See CONTRIBUTING on how to contribute to the project.
The MIT License (MIT). Please see LICENSE for more information.