PHPackages                             mmdm/sim-auth - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Authentication &amp; Authorization](/categories/authentication)
4. /
5. mmdm/sim-auth

ActiveLibrary[Authentication &amp; Authorization](/categories/authentication)

mmdm/sim-auth
=============

A simple yet nice authentication library

v0.2.17(3y ago)131MITPHPPHP &gt;=7.2

Since Apr 28Pushed 3y ago1 watchersCompare

[ Source](https://github.com/mmdm95/sim-auth)[ Packagist](https://packagist.org/packages/mmdm/sim-auth)[ RSS](/packages/mmdm-sim-auth/feed)WikiDiscussions master Synced 1w ago

READMEChangelogDependencies (3)Versions (6)Used By (0)

Simplicity Authentication
=========================

[](#simplicity-authentication)

A library for authentication.

Install
-------

[](#install)

**composer**

```
composer require mmdm/sim-auth
```

Or you can simply download zip file from github and extract it, then put file to your project library and use it like other libraries.

Just add line below to autoload files:

```
require_once 'path_to_library/autoloader.php';
```

and you are good to go.

### But Wait

[](#but-wait)

Why rough it when `composer` is here to help us. Please use composer to enjoy this library ☻

Architecture
------------

[](#architecture)

This library is mostly for role-based and resource-based architecture together. Look at below information:

**Collation:**

It should be `utf8mb4_unicode_ci` because it is a very nice collation. For more information about differences between `utf8` and `utf8mb4`in `general` and `unicode` please see [this link](https://stackoverflow.com/questions/766809/whats-the-difference-between-utf8-general-ci-and-utf8-unicode-ci) from `stackoverflow`

Note: Please use `utf8mb4` collations.

**Table:**

- users

    This table contains all users.

    Least columns of this table should be:

    - id (INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO\_INCREMENT)
    - username (VARCHAR(20) NOT NULL)
    - password (VARCHAR(255) NOT NULL)
- api\_keys

    This table is to store all api users and the keys.

    Least columns of this table should be:

    - id (INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO\_INCREMENT)
    - username (VARCHAR(20) NOT NULL)
    - api\_key (VARCHAR(255) NOT NULL)
- roles

    This table contains all roles.

    Least columns of this table should be:

    - id (INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO\_INCREMENT)
    - name (VARCHAR(20))
    - description (VARCHAR(100))
    - is\_admin (TINYINT(1) UNSIGNED NOT NULL DEFAULT 0)
- resources

    This table contains all resources.

    Least columns of this table should be:

    - id (INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO\_INCREMENT)
    - name (VARCHAR(20))
    - description (VARCHAR(100))
- sessions

    This table contains all UUIDs that generate for a user.

    Least columns of this table should be:

    - id (INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO\_INCREMENT)
    - uuid (VARCHAR(36))
    - user\_id (INT(11) UNSIGNED NOT NULL)
    - ip\_address (VARCHAR(16))
    - device (TEXT)
    - browser (TEXT)
    - platform (TEXT)
    - expire\_at (INT(11) UNSIGNED)
    - created\_at (INT(11) UNSIGNED)

**Table Relations:**

- user\_role

    This table contains all users and their roles.

    Least columns of this table should be:

    - id (INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO\_INCREMENT)
    - user\_id (INT(11) UNSIGNED NOT NULL)
    - role\_id (INT(11) UNSIGNED NOT NULL)

    **Constraints:**

    - ADD CONSTRAINT fk\_urp\_u FOREIGN KEY(user\_id) REFERENCES users(id)
    - ADD CONSTRAINT fk\_urp\_r FOREIGN KEY(role\_id) REFERENCES roles(id)
- user\_res\_perm

    This table contains all users, resources and their permission.

    Least columns of this table should be:

    - id (INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO\_INCREMENT)
    - user\_id (INT(11) UNSIGNED NOT NULL)
    - resource\_id (INT(11) UNSIGNED NOT NULL)
    - perm\_id (INT(11) UNSIGNED NOT NULL)
    - is\_allow (TINYINT(1) UNSIGNED NOT NULL DEFAULT 1)

    **Constraints:**

    - ADD CONSTRAINT fk\_upp\_u FOREIGN KEY(user\_id) REFERENCES users(id)
    - ADD CONSTRAINT fk\_upp\_pa FOREIGN KEY(resource\_id) REFERENCES resources(id)
- role\_res\_perm

    This table contains all roles, resources and their permission.

    Least columns of this table should be:

    - id (INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO\_INCREMENT)
    - role\_id (INT(11) UNSIGNED NOT NULL)
    - resource\_id (INT(11) UNSIGNED NOT NULL)
    - perm\_id (INT(11) UNSIGNED NOT NULL)

    **Constraints:**

    - ADD CONSTRAINT fk\_rpp\_r FOREIGN KEY(role\_id) REFERENCES roles(id)
    - ADD CONSTRAINT fk\_rpp\_pa FOREIGN KEY(resource\_id) REFERENCES resources(id)

How to use
----------

[](#how-to-use)

First of all you need a `PDO` connection like below:

```
$host = '127.0.0.1';
$db = 'database name';
$user = 'username';
$pass = 'password';
// this is very nice collation to use
$charset = 'utf8mb4';

$dsn = "mysql:host={$host};dbname={$db};charset={$charset}";
$options = [
    // add this option to show exception on any bad condition
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
];
try {
    $pdo = new PDO($dsn, $user, $pass, $options);
} catch (\PDOException $e) {
    throw new \PDOException($e->getMessage(), (int)$e->getCode());
}
```

\[Optionally\] Second you need two keys to protect stored credentials. These two keys should be two base64 coded strings. Just generate two passwords and encode them to base64 strings. For more info about these two keys see [this link](https://github.com/mmdm95/sim-crypt)

### Available Connections

[](#available-connections)

- DBAuth
- APIAuth

Shared Methods
--------------

[](#shared-methods)

### AbstractBaseAuth

[](#abstractbaseauth)

All connections have below methods:

```
__construct(PDO $pdo_instance, ?array $config = null);
```

`$pdo_instance`: Argument is `PDO` connection that explained above.

`$config`: To change the `Architecture` mentioned above, you can pass and array to change the config or `null` for default behavior.

#### `setConfig(array $config, bool $merge_config = false)`

[](#setconfigarray-config-bool-merge_config--false)

With this method you can change `Architecture` signatures. If you need to merge default configuration and passed configuration, you can pass `true` as seconds parameter.

#### `runConfig()`

[](#runconfig)

The configuration can build internally by library. Thi function parse the configuration of library.

**Note:** If you build tables from configuration by yourself, there is no need to call this method, but please before any table creation, call this method to make your tables.

#### `addResources(array $resources)`

[](#addresourcesarray-resources)

Add some resources to database.

$resources array has following structure:

```
// an array of arrays
[
  // this array is columns of resource table and their values
  [
    column1 => value1,
    column2 => value2,
  ],
  [
    column1 => value3,
    column2 => value4,
  ],
  ...
]
```

#### `removeResources(array $resources)`

[](#removeresourcesarray-resources)

Remove some resources from database.

**Note:** $resources should be array of resources' name or resources' id.

#### `hasResource($resource): bool`

[](#hasresourceresource-bool)

Check if a resource is exists or not.

**Note:** $resources should be array of resources' name or resources' id.

#### `getResources(): array`

[](#getresources-array)

Get all resources.

**Note:** It returns all columns of resources table.

#### `getResourcesNames(): array`

[](#getresourcesnames-array)

Get all resources `name` column.

#### `addRoles(array $roles)`

[](#addrolesarray-roles)

Add some roles to database.

$roles array has following structure:

```
[
  // this array is columns of role table and their values
  [
    column1 => value1,
    column2 => value2,
  ],
  [
    column1 => value3,
    column2 => value4,
  ],
  ...
]
```

#### `removeRoles(array $roles)`

[](#removerolesarray-roles)

Remove some roles from database.

**Note:** $roles should be array of roles' name or roles' id.

#### `hasRole(string $role): bool`

[](#hasrolestring-role-bool)

Check if a role is exists or not. You must pass the role name as parameter. It is because of convenient to use constants as roles' names.

#### `getRoles(): array`

[](#getroles-array)

Get all roles.

**Note:** It returns all columns of roles table.

#### `getAdminRoles(): array`

[](#getadminroles-array)

Get all admin roles.

**Note:** It returns all columns of roles table.

#### `getRolesName(): array`

[](#getrolesname-array)

Get all roles `name` column.

#### `getAdminRolesName(): array`

[](#getadminrolesname-array)

Get all admin's roles `name` column.

#### `allowRole($resource, array $permission, $role)`

[](#allowroleresource-array-permission-role)

Make a role to allow a resource with a specific permission.

**Note:** You can pass resource's `name` or `id`.

**Note:** You can pass role's `name` or `id`.

#### `disallowRole($resource, array $permission, $role)`

[](#disallowroleresource-array-permission-role)

Make a role to disallow a resource with a specific permission.

**Note:** You can pass resource's `name` or `id`.

**Note:** You can pass role's `name` or `id`.

### AbstractAuth

[](#abstractauth)

Some connections (that will say in each connection) have below methods:

```
__construct(
    PDO $pdo_instance,
    string $namespace = 'default',
    array $crypt_keys = [],
    int $storage_type = IAuth::STORAGE_DB,
    ?array $config = null
);
```

`$pdo_instance`: See constructor of [AbstractBaseAuth](#abstractbaseauth).

`$namespace`: You can specify a namespace to separate each logic of your application. For example a `home` namespace for users login and an `admin` namespace for administrators logic.

`$crypt_keys`: To protect your cookies and sessions information, you can specify two keys on below structure:

```
[
    'main' => main key of encryption,
    'assured' => assured key of encryption
]

```

If you don't need any encryption (that is not suggested), you can pass an empty array as value of the parameter.

`$storage_type`: The storage type tell authentication library to store needed information in where. There are three types of storage:

- IAuth::STORAGE\_SESSION

    This storage type, store data in the php session
- IAuth::STORAGE\_COOKIE

    This storage type, store data in the cookie
- IAuth::STORAGE\_DB (Suggested)

    This storage type, store data in the database with a uuid

(They are available under `Sim\Auth\Interfaces` namespace)

`$config`: See constructor of [AbstractBaseAuth](#abstractbaseauth).

#### `getStatus(): int`

[](#getstatus-int)

There are four types of status for better management of authentication:

- IAuth::STATUS\_NONE

    When there is no session/cookie or anything, the status is none
- IAuth::STATUS\_ACTIVE

    When a user logged in to his/her account, the status will be active
- IAuth::STATUS\_EXPIRE

    After a user login it'll set a session/cookie for expiration time of login. If it expires, it'll change status to expire.
- IAuth::STATUS\_SUSPEND

    After a user login it'll set a session/cookie for suspend time of login. If there is no request for a while, it'll change status to suspend.

(They are available under `Sim\Auth\Interfaces` namespace)

#### `isLoggedIn(): bool`

[](#isloggedin-bool)

Check if a user is logged in or not.

#### `isExpired(): bool`

[](#isexpired-bool)

Check if a user's session/cookie is expired or not.

#### `isSuspended(): bool`

[](#issuspended-bool)

Check if a user's session/cookie is suspended or not.

#### `isNone(): bool`

[](#isnone-bool)

Check if there is no status (if status is none or not).

#### `extendSuspendTime()`

[](#extendsuspendtime)

If it need to extend suspend time to start over the time, this method helps.

#### `setExpiration($timestamp)`

[](#setexpirationtimestamp)

Set expiration time for user's login.

**Note:** Just enter the amount of time you need from now in seconds like 300.

**Note:** Also can pass string time like \[+5 days\]

#### `getExpiration(): int`

[](#getexpiration-int)

Get login expiration time.

**Note:** Default expiration time is `31536000` seconds that is `1 year`.

#### `setSuspendTime($timestamp)`

[](#setsuspendtimetimestamp)

Set suspend time for user's login.

**Note:** Just enter the amount of time you need from now in seconds like 300.

**Note:** Also can pass string time like \[+5 days\]

#### `getSuspendTime(): int`

[](#getsuspendtime-int)

Get login suspend time.

**Note:** Default suspend time is `1800` seconds that is `30 minutes`.

#### `setStorageType(int $type)`

[](#setstoragetypeint-type)

Set storage type of storing data. Storage types are explained above.

#### `getStorageType(): int`

[](#getstoragetype-int)

Get storage type for storing data.

**Note:** Default storage type is `IAuth::STORAGE_DB`.

#### `setNamespace(string $namespace)`

[](#setnamespacestring-namespace)

Set namespace to separate your logic.

#### `getNamespace(): string`

[](#getnamespace-string)

Get current namespace.

**Note:** Default namespace is `default`.

#### `loginWithID(int $id)`

[](#loginwithidint-id)

Make a login with user's id.

#### `resume()`

[](#resume)

If there were a login before, it resumes that login.

#### `logout()`

[](#logout)

Make user logout and delete and destroy any stored data.

#### `getSessionUUID($username = null): array`

[](#getsessionuuidusername--null-array)

Get a user's UUIDs.

**Note:** It only works with \[IAuth::STORAGE\_DB\] otherwise it'll not work.

**Note:** You can pass user's `username` or `id` to get UUIDs or pass `null` or nothing to get current user's UUIDs.

#### `destroySession(string $session_uuid): bool`

[](#destroysessionstring-session_uuid-bool)

Destroy a UUID session from database.

**Note:** It only works with \[IAuth::STORAGE\_DB\] otherwise it'll not work.

#### `getCurrentUser(): ?array`

[](#getcurrentuser-array)

Get current user's credentials.

#### `isAllow($resource, int $permission, $username = null): bool`

[](#isallowresource-int-permission-username--null-bool)

Check if a user is allow to have a permission to a specific resource or not.

**Note:** You can pass resource's `name` or `id`.

**Note:** You can pass user's `username` or `id` to check or pass `null` or nothing to check for current user.

Permissions are one of below:

- IAuth::PERMISSION\_CREATE
- IAuth::PERMISSION\_READ
- IAuth::PERMISSION\_UPDATE
- IAuth::PERMISSION\_DELETE

(They are available under `Sim\Auth\Interfaces` namespace)

#### `allowUser($resource, array $permission, $username = null)`

[](#allowuserresource-array-permission-username--null)

Make a user to allow a resource with a specific permission.

**Note:** You can pass resource's `name` or `id`.

**Note:** You can pass user's `username` or `id` to check or pass `null` or nothing to check for current user.

#### `disallowUser($resource, array $permission, $username = null)`

[](#disallowuserresource-array-permission-username--null)

Make a user to disallow a resource with a specific permission.

**Note:** You can pass resource's `name` or `id`.

**Note:** You can pass user's `username` or `id` to check or pass `null` or nothing to check for current user.

#### `getUserRole($username): array`

[](#getuserroleusername-array)

Get a user's roles.

**Note:** You can pass user's `username` or `id`.

#### `getCurrentUserRole(): array`

[](#getcurrentuserrole-array)

Get current user's roles.

#### `userHasRole($role, $username = null): bool`

[](#userhasrolerole-username--null-bool)

Check user has a specific role

**Note:** You can pass user's `username` or `id`.

#### `addRoleToUser(array $role, $username = null)`

[](#addroletouserarray-role-username--null)

Add some roles to a user.

**Note:** You should pass an array of roles' name.

**Note:** You can pass user's `username` or `id` to add role to or pass `null` or nothing to add roles to current user.

#### `isAdmin($username = null): bool`

[](#isadminusername--null-bool)

Check if a user is admin or not.

**Note:** You can pass user's `username` or `id` to check or pass `null` or nothing to check for current user.

#### `quoteSingleName(string $name): string`

[](#quotesinglenamestring-name-string)

Quote a column or table name or anything that needed to quote.

**Note:** It is tested with `mysql` but not with `sql server`.

### Usage of each connection

[](#usage-of-each-connection)

### `DBAuth`

[](#dbauth)

Contains all of [AbstractAuth](#abstractauth) and below extra information.

```
// this is constructor
$auth = new DBAuth (
    PDO $pdo_instance,
    string $namespace = 'default',
    array $crypt_keys = [],
    $algo = PASSWORD_BCRYPT,
    int $storage_type = IAuth::STORAGE_DB,
    ?array $config = null
);
```

`$pdo_instance`: See constructor of [AbstractAuth](#abstractauth).

`$namespace`: See constructor of [AbstractAuth](#abstractauth).

`$crypt_keys`: See constructor of [AbstractAuth](#abstractauth).

`$algo`: Algorithm to verify the password. It could be one of `PASSWORD_DEFAULT` or `PASSWORD_BCRYPT` to verify with `password_verify` function or other strings to verify with `hash` function.

`$storage_type`: See constructor of [AbstractAuth](#abstractauth).

`$config`: See constructor of [AbstractAuth](#abstractauth).

#### `login(array $credentials, string $extra_query = null, array $bind_values = [])`

[](#loginarray-credentials-string-extra_query--null-array-bind_values--)

`$credentials` should be like below structure:

```
// keys MUST be same as below
[
  'username' => provided username,
  'password' => provided password,
]
```

If there are more conditions to check for a user, you can pass them by `$extra_query` parameter and it MUST be parameterized.

**Note:** You should know that the login will check inside of a joined tables of `users` and `roles`. So if there is a condition, it's better to have the table's name before any column.

**Note:** You should quote your columns by yourself or use `quoteSingleName` that explained above.

```
// for example check if user is activated
$auth->login([
    'username' => provided username,
    'password' => provided password,
], 'users.is_active=:active', [
    'active' => 1,
]);

// to see if login has succeed
$isLoggedIn = $auth->isLoggedIn();
```

**Note:** To get the error of login, put it in try, catch block.

```
try {
    $auth->login([
        'username' => provided username,
        'password' => provided password,
    ]);
} catch (\Sim\Auth\Exceptions\IncorrectPasswordException $e) {
    // do something according to error
    // eg.
    echo 'Username or password is incorrect!';
} catch (\Sim\Auth\Exceptions\InvalidUserException $e) {
    // do something according to error
    // eg.
    echo 'Username or password is incorrect!';
} catch (\Sim\Auth\Interfaces\IDBException $e) {
    // do something according to error
    // eg.
    echo 'Failed database connection!';
}
```

#### `loginWithUsername(string $username, string $extra_query = null, array $bind_values = [])`

[](#loginwithusernamestring-username-string-extra_query--null-array-bind_values--)

If there are more conditions to check for a user, you can pass them by `$extra_query` parameter and it MUST be parameterized.

**Note:** You should know that the login will check inside of a joined tables of `users` and `roles`. So if there is a condition, it's better to have the table's name before any column.

**Note:** You should quote your columns by yourself or use `quoteSingleName` that explained before.

```
// for example check if user is activated
$auth->login(
  'provided username',
  'users.is_active=:active',
  [
    'active' => 1,
  ]
);

// to see if login has succeed
$isLoggedIn = $auth->isLoggedIn();
```

**Note:** To get the error of login, put it in try, catch block.

```
try {
    $auth->login('provided username');
} catch (\Sim\Auth\Exceptions\InvalidUserException $e) {
    // do something according to error
    // eg.
    echo 'Username or password is incorrect!';
} catch (\Sim\Auth\Interfaces\IDBException $e) {
    // do something according to error
    // eg.
    echo 'Failed database connection!';
}
```

---

### AbstractAPIAuth

[](#abstractapiauth)

Contains all of [AbstractBaseAuth](#abstractbaseauth).

```
__construct(
    PDO $pdo_instance,
    ?array $config = null
);
```

`$pdo_instance`: See constructor of [AbstractBaseAuth](#abstractbaseauth).

`$config`: See constructor of [AbstractBaseAuth](#abstractbaseauth).

#### `isAllow($resource, int $permission, $username = null): bool`

[](#isallowresource-int-permission-username--null-bool-1)

Check if a user is allow to have a permission to a specific resource or not.

**Note:** You can pass resource's `name` or `id`.

**Note:** You can pass user's `username` or `id` to check or pass `null` or nothing to check for current user.

Permissions are one of below:

- IAuth::PERMISSION\_CREATE
- IAuth::PERMISSION\_READ
- IAuth::PERMISSION\_UPDATE
- IAuth::PERMISSION\_DELETE

(They are available under `Sim\Auth\Interfaces` namespace)

#### `getUserRole($username): array`

[](#getuserroleusername-array-1)

Get a user's roles.

**Note:** You can pass user's `username` or `id`.

#### `getCurrentUserRole(): array`

[](#getcurrentuserrole-array-1)

Get current user's roles.

#### `addRoleToUser(array $roles, $username = null)`

[](#addroletouserarray-roles-username--null)

Add some roles to a user.

**Note:** You should pass an array of roles' name.

**Note:** You can pass user's `username` or `id` to add role to or pass `null` or nothing to add roles to current user.

#### `isAdmin($username = null): bool`

[](#isadminusername--null-bool-1)

Check if a user is admin or not.

**Note:** You can pass user's `username` or `id` to check or pass `null` or nothing to check for current user.

---

### `APIAuth`

[](#apiauth)

Contains all of [AbstractAPIAuth](#abstractapiauth) and below extra information.

#### `validate(array $credentials, string $extra_query = null, array $bind_values = []): bool`

[](#validatearray-credentials-string-extra_query--null-array-bind_values---bool)

`$credentials` should be like below structure:

```
// keys MUST be same as below
[
  'username' => provided username,
  'api_key' => provided api key,
]
```

If there are more conditions to check for a user, you can pass them by `$extra_query` parameter and it MUST be parameterized.

**Note:** You should know that the verify will check inside of a joined tables of `api_keys` and `roles`. So if there is a condition, it's better to have the table's name before any column.

**Note:** You should quote your columns by yourself or use `quoteSingleName` that explained before.

```
// for example check if user is allowed or something
$auth->validate([
    'username' => provided username,
    'api_key' => provided api key,
], 'api_keys.allowed=:allow', [
    'allow' => 1,
]);
```

**Note:** To get the error of validateAPI, put it in try, catch block.

```
try {
    $auth->validate([
        'username' => provided username,
        'api_key' => provided api key,
    ]);
} catch (\Sim\Auth\Exceptions\IncorrectAPIKeyException $e) {
    // do something according to error
    // eg.
    echo 'Username or api key is incorrect!';
} catch (\Sim\Auth\Interfaces\IDBException $e) {
    // do something according to error
    // eg.
    echo 'Failed database connection!';
}
```

#### `validateAPI(string $api_key, string $extra_query = null, array $bind_values = []): bool`

[](#validateapistring-api_key-string-extra_query--null-array-bind_values---bool)

If there are more conditions to check for a user, you can pass them by `$extra_query` parameter and it MUST be parameterized.

**Note:** You should know that the verify will check inside of a joined tables of `api_keys` and `roles`. So if there is a condition, it's better to have the table's name before any column.

**Note:** You should quote your columns by yourself or use `quoteSingleName` that explained before.

```
// for example check if user is allowed or something
$auth->validateAPI('provided api key', 'api_keys.allowed=:allow', [
    'allow' => 1,
]);
```

**Note:** To get the error of validate, put it in try, catch block.

```
try {
    $auth->validateAPI('provided api key');
} catch (\Sim\Auth\Exceptions\IncorrectAPIKeyException $e) {
    // do something according to error
    // eg.
    echo 'Api key is invalid!';
} catch (\Sim\Auth\Interfaces\IDBException $e) {
    // do something according to error
    // eg.
    echo 'Failed database connection!';
}
```

Dependencies
============

[](#dependencies)

There is some dependencies here including:

[Crypt](https://github.com/mmdm95/sim-crypt) library. With this feature, if any session/cookie hijacking happens, they can't see actual data because it is encrypted.

[Cookie](https://github.com/mmdm95/sim-cookie) library to manipulate cookies.

[Session](https://github.com/mmdm95/sim-session) library to manipulate sessions.

[Agent](https://github.com/jenssegers/agent) library to get user's device and browser information to store in `sessions` table

And some dependency from [Agent](https://github.com/jenssegers/agent) library.

License
=======

[](#license)

Under MIT license.

###  Health Score

21

—

LowBetter than 18% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity9

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity41

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~130 days

Total

5

Last Release

1326d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/d955ebaae3fe602e6ad26c16422f6ab25a61a436fd7f08425a5be5c73ef9025c?d=identicon)[mmdm95](/maintainers/mmdm95)

---

Top Contributors

[![mmdm95](https://avatars.githubusercontent.com/u/26489185?v=4)](https://github.com/mmdm95 "mmdm95 (162 commits)")

### Embed Badge

![Health badge](/badges/mmdm-sim-auth/health.svg)

```
[![Health](https://phpackages.com/badges/mmdm-sim-auth/health.svg)](https://phpackages.com/packages/mmdm-sim-auth)
```

###  Alternatives

[lab404/laravel-auth-checker

Laravel Auth Checker allows you to log users authentication, devices authenticated from and lock intrusions.

223164.9k2](/packages/lab404-laravel-auth-checker)[cjmellor/browser-sessions

A Laravel package to enable users to manage and monitor their active browser sessions. Allows users to view devices where they are logged in and provides options to terminate unrecognized or all sessions, enhancing account security

26752.2k](/packages/cjmellor-browser-sessions)[asundust/auth-captcha

Sliding captcha for Laravel-Admin auth, Multiple platform support / Laravel-Admin登录 滑动验证插件 多平台支持

593.6k](/packages/asundust-auth-captcha)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
