PHPackages                             detain/oauth2-server-mydb-storage - 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. [Database &amp; ORM](/categories/database)
4. /
5. detain/oauth2-server-mydb-storage

ActiveLibrary[Database &amp; ORM](/categories/database)

detain/oauth2-server-mydb-storage
=================================

MyDb storage adapter implementing the thephpleague/oauth2-server (4.x) storage interfaces.

2551PHPCI passing

Since May 7Pushed 4d ago1 watchersCompare

[ Source](https://github.com/detain/oauth2-server-mydb-storage)[ Packagist](https://packagist.org/packages/detain/oauth2-server-mydb-storage)[ RSS](/packages/detain-oauth2-server-mydb-storage/feed)WikiDiscussions master Synced today

READMEChangelogDependenciesVersions (1)Used By (0)

oauth2-server-mydb-storage
==========================

[](#oauth2-server-mydb-storage)

[![Software License](https://camo.githubusercontent.com/55c0218c8f8009f06ad4ddae837ddd05301481fcf0dff8e0ed9dadda8780713e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265)](LICENSE)[![PHP from Packagist](https://camo.githubusercontent.com/60177badd05fa360807fbdb608bd1470e1d39f7faf420faaaa43f267833bb8ef/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f64657461696e2f6f61757468322d7365727665722d6d7964622d73746f726167652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/detain/oauth2-server-mydb-storage)

A [`MyDb\Generic`](https://packagist.org/packages/detain/db_abstraction)–backed storage adapter for [`thephpleague/oauth2-server` **4.x**](https://github.com/thephpleague/oauth2-server/tree/4.1.7).

It implements the six storage interfaces from the league's 4.x API (`AccessTokenInterface`, `AuthCodeInterface`, `ClientInterface`, `RefreshTokenInterface`, `ScopeInterface`, `SessionInterface`) so that an existing MyDb-driven application can plug an OAuth 2.0 server straight into its current MySQL connection without going through PDO directly.

> **Compatibility note** — this package targets the 4.x line of `league/oauth2-server`. Versions 5.x and later from the league were a ground-up rewrite using a different namespace layout (`Entities\…RepositoryInterface` rather than `Entity\…Interface`). If you need a v8-era adapter, look elsewhere or open a PR.

Requirements
------------

[](#requirements)

ComponentVersionPHP7.0 or newer`ext-pdo`enabled`league/oauth2-server``^4.1``detain/db_abstraction`anyPHPUnit (dev)`^9.0`Installation
------------

[](#installation)

```
composer require detain/oauth2-server-mydb-storage
```

Schema
------

[](#schema)

Apply [`sql/oauth2.sql`](sql/oauth2.sql) to create the ten tables the adapters expect:

TablePurpose`oauth_clients`Registered OAuth2 client applications`oauth_client_redirect_uris`Allowed redirect URIs per client`oauth_scopes`Available scopes (e.g. `basic`, `email`)`oauth_sessions`Active sessions linking owner ↔ client`oauth_session_scopes`Scopes granted to each session`oauth_access_tokens`Issued bearer access tokens`oauth_access_token_scopes`Scopes attached to each access token`oauth_auth_codes`Pending authorization codes`oauth_auth_code_scopes`Scopes attached to each auth code`oauth_refresh_tokens`Issued refresh tokensThe schema FK-references the host project's `accounts` table for `oauth_clients.account_id` and `oauth_sessions.account_id`. If you do not have an `accounts` table, edit those constraints out before applying.

Usage
-----

[](#usage)

```
use Detain\OAuth2\Server\Repository\MyDb\AccessTokenRepository;
use Detain\OAuth2\Server\Repository\MyDb\AuthCodeRepository;
use Detain\OAuth2\Server\Repository\MyDb\ClientRepository;
use Detain\OAuth2\Server\Repository\MyDb\RefreshTokenRepository;
use Detain\OAuth2\Server\Repository\MyDb\ScopeRepository;
use Detain\OAuth2\Server\Repository\MyDb\SessionRepository;
use League\OAuth2\Server\AuthorizationServer;
use League\OAuth2\Server\ResourceServer;
use MyDb\Mysqli\Db;

$db = new Db('mydb', 'myuser', 'mypassword');

// Resource Server (token introspection / protected APIs)
$resourceServer = new ResourceServer(
    new SessionRepository($db),
    new AccessTokenRepository($db),
    new ClientRepository($db),
    new ScopeRepository($db)
);

// Authorization Server (token issuance / grants)
$authorizationServer = new AuthorizationServer();
$authorizationServer->setSessionStorage(new SessionRepository($db));
$authorizationServer->setAccessTokenStorage(new AccessTokenRepository($db));
$authorizationServer->setClientStorage(new ClientRepository($db));
$authorizationServer->setScopeStorage(new ScopeRepository($db));
$authorizationServer->setAuthCodeStorage(new AuthCodeRepository($db));
$authorizationServer->setRefreshTokenStorage(new RefreshTokenRepository($db));
```

> **Heads-up** — the league's 4.x API uses **`set*Storage`** / **`get*Storage`** rather than the `set*Repository` naming used in 5.x and later. The class names in this package retain the `…Repository` suffix for historical reasons but the league interfaces they implement are `League\OAuth2\Server\Storage\*Interface`.

Database query pattern
----------------------

[](#database-query-pattern)

Repositories use the MyDb string-escape pattern, never PDO prepared statements:

```
// SELECT
$this->db->query('SELECT * FROM oauth_access_tokens WHERE access_token = "'.$this->db->real_escape($token).'"');
if ($this->db->num_rows() === 1) {
    $this->db->next_record(MYSQLI_ASSOC);
    $row = $this->db->Record;
}

// INSERT (helper preserves NULL semantics for nullable columns)
$values = [
    $this->sqlValue($token),
    $this->sqlValue($expireTime),
    $this->sqlValue($sessionId),
];
$this->db->query('INSERT INTO oauth_access_tokens (access_token, expire_time, session_id) VALUES ('.implode(',', $values).')');

// DELETE
$this->db->query('DELETE FROM oauth_access_tokens WHERE access_token = "'.$this->db->real_escape($token->getId()).'"');
```

Always:

- Pass user input through `$this->db->real_escape()` (or `$this->sqlValue()`for nullable values) — never interpolate raw `$_GET` / `$_POST`.
- Check `$this->db->num_rows() === 1` before calling `next_record(MYSQLI_ASSOC)`.
- Read columns through `$this->db->Record['column_name']`.
- Loop multi-row results with `while ($this->db->next_record(MYSQLI_ASSOC))`.

Conventions
-----------

[](#conventions)

- All `src/` classes extend [`src/Repository.php`](src/Repository.php) and implement the matching `League\OAuth2\Server\Storage\*Interface`.
- Hydrate entities via `(new FooEntity($this->server))->hydrate(['id' => …, 'description' => …])`or with the `setId()` / `setExpireTime()` / `setRedirectUri()` setters.
- Return `null` (not `false`) when a record is not found.
- Test files in `tests/` are named `{Name}RepositoryTest.php` and extend `MyDbTest` (defined in `tests/bootstrap.php`).
- Cover, at minimum: `get()` success + failure, `create()`, `delete()`, `getScopes()`, `associateScope()`.
- Seed test data with `$this->db->exec("INSERT INTO …")` inside each test method.

Running the test suite
----------------------

[](#running-the-test-suite)

```
composer install
./vendor/bin/phpunit
```

or, equivalently:

```
composer test
```

The suite ships with an in-memory SQLite stub (`tests/bootstrap.php#TestDb`) that re-implements just enough of the MyDb public surface (`query`, `next_record`, `num_rows`, `Record`, `real_escape`, `qr`, `prepare`, `exec`, `lastInsertId`, ...) to exercise the repositories without spinning up a real MySQL server.

Live OAuth flow examples
------------------------

[](#live-oauth-flow-examples)

The examples below assume you have already inserted a client into `oauth_clients` and given it a redirect URI in `oauth_client_redirect_uris`.

### Client-credentials grant

[](#client-credentials-grant)

```
curl -X POST 'https://example.com/oauth/server/client_credentials.php/access_token' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -H 'Accept: 1.0' \
  --data-urlencode 'grant_type=client_credentials' \
  --data-urlencode 'client_id=rocketchat_2773' \
  --data-urlencode 'client_secret=s3cr3t' \
  --data-urlencode 'scope=basic email'
```

### Password grant

[](#password-grant)

```
curl -X POST 'https://example.com/oauth/server/password.php/access_token' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -H 'Accept: 1.0' \
  --data-urlencode 'grant_type=password' \
  --data-urlencode 'client_id=rocketchat_2773' \
  --data-urlencode 'client_secret=s3cr3t' \
  --data-urlencode 'username=alex' \
  --data-urlencode 'password=whisky' \
  --data-urlencode 'scope=basic email'
```

### Refresh-token grant

[](#refresh-token-grant)

Replace `{{REFRESH_TOKEN}}` with a refresh token returned by one of the grants above.

```
curl -X POST 'https://example.com/oauth/server/refresh_token.php/access_token' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -H 'Accept: 1.0' \
  --data-urlencode 'grant_type=refresh_token' \
  --data-urlencode 'client_id=rocketchat_2773' \
  --data-urlencode 'client_secret=s3cr3t' \
  --data-urlencode 'refresh_token={{REFRESH_TOKEN}}'
```

License
-------

[](#license)

Released under the [MIT License](LICENSE).

Origin
------

[](#origin)

This package began as a port of [`DavidWiesner/oauth2-server-pdo`](https://github.com/DavidWiesner/oauth2-server-pdo)to the MyDb abstraction used by [InterServer](https://www.interserver.net)'s internal billing / hosting platform.

###  Health Score

27

—

LowBetter than 49% of packages

Maintenance65

Regular maintenance activity

Popularity20

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity11

Early-stage or recently created project

 Bus Factor1

Top contributor holds 96.3% 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.

### Community

Maintainers

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

---

Top Contributors

[![detain](https://avatars.githubusercontent.com/u/1364504?v=4)](https://github.com/detain "detain (26 commits)")[![mend-bolt-for-github[bot]](https://avatars.githubusercontent.com/in/16809?v=4)](https://github.com/mend-bolt-for-github[bot] "mend-bolt-for-github[bot] (1 commits)")

---

Tags

authauthenticationauthorizationbearer-tokencomposer-packagedatabaseleague-oauth2mysqlmysqlioauthoauth2oauth2-serveroauth2-storagepdophpphp-librarystorage-adapterthephpleaguetoken-storageuser-management

### Embed Badge

![Health badge](/badges/detain-oauth2-server-mydb-storage/health.svg)

```
[![Health](https://phpackages.com/badges/detain-oauth2-server-mydb-storage/health.svg)](https://phpackages.com/packages/detain-oauth2-server-mydb-storage)
```

###  Alternatives

[doctrine/orm

Object-Relational-Mapper for PHP

10.2k285.3M6.2k](/packages/doctrine-orm)[jdorn/sql-formatter

a PHP SQL highlighting library

3.9k115.1M102](/packages/jdorn-sql-formatter)[illuminate/database

The Illuminate Database package.

2.8k52.4M9.4k](/packages/illuminate-database)[mongodb/mongodb

MongoDB driver library

1.6k64.0M546](/packages/mongodb-mongodb)[ramsey/uuid-doctrine

Use ramsey/uuid as a Doctrine field type.

90340.3M211](/packages/ramsey-uuid-doctrine)[reliese/laravel

Reliese Components for Laravel Framework code generation.

1.7k3.4M16](/packages/reliese-laravel)

PHPackages © 2026

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