PHPackages                             npr/npr-one-backend-proxy - 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. npr/npr-one-backend-proxy

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

npr/npr-one-backend-proxy
=========================

A server-side proxy for interacting with the NPR One API's authorization server

v4.3.4(3y ago)66.7k2[3 issues](https://github.com/npr/npr-one-backend-proxy-php/issues)[3 PRs](https://github.com/npr/npr-one-backend-proxy-php/pulls)Apache-2.0PHPPHP &gt;=7.3.0CI failing

Since Jul 8Pushed 8mo ago44 watchersCompare

[ Source](https://github.com/npr/npr-one-backend-proxy-php)[ Packagist](https://packagist.org/packages/npr/npr-one-backend-proxy)[ Docs](https://dev.npr.org)[ RSS](/packages/npr-npr-one-backend-proxy/feed)WikiDiscussions main Synced today

READMEChangelog (10)Dependencies (6)Versions (25)Used By (0)

NPR One Backend Proxy
=====================

[](#npr-one-backend-proxy)

A PHP-based server-side proxy for interacting with the [NPR One API](https://dev.npr.org/api/)'s authorization server. Use this proxy to secure your OAuth2 credentials.

[![Packagist](https://camo.githubusercontent.com/6873029374f5b40a65d3692f60a033260892d631509e39ec9aa78cdac116e06f/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6e70722f6e70722d6f6e652d6261636b656e642d70726f78792e7376673f6d61784167653d32353932303030)](https://packagist.org/packages/npr/npr-one-backend-proxy) [![Packagist](https://camo.githubusercontent.com/9350f657936cccf405789c94a523602bf303d1a95c5b6d9274abda7625823482/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f6e70722f6e70722d6f6e652d6261636b656e642d70726f78792e7376673f6d61784167653d32353932303030)](https://github.com/npr/npr-one-backend-proxy-php/blob/main/LICENSE.md) [![Packagist](https://camo.githubusercontent.com/c076745f49a0995e058a872ea87cdeefa7f7f50f3c321b8d6e4eb0db17bdf560/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6e70722f6e70722d6f6e652d6261636b656e642d70726f78792e7376673f6d61784167653d32353932303030)](https://packagist.org/packages/npr/npr-one-backend-proxy) [![Build Status](https://camo.githubusercontent.com/5ab27d497f80560caf618da02823186017525079ff53489c5082deacf147d1fd/68747470733a2f2f7472617669732d63692e6f72672f6e70722f6e70722d6f6e652d6261636b656e642d70726f78792d7068702e7376673f6272616e63683d6d61696e)](https://travis-ci.org/npr/npr-one-backend-proxy-php) [![Coverage Status](https://camo.githubusercontent.com/9b1c291bbb1cce3e6ccbcae516f89d2c8f26702b0091c1f7df1d0479394aa05c/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6769746875622f6e70722f6e70722d6f6e652d6261636b656e642d70726f78792d7068702f62616467652e7376673f6272616e63683d6d61696e)](https://coveralls.io/github/npr/npr-one-backend-proxy-php?branch=main)

##### Table of Contents

[](#table-of-contents)

- [Background](#background)
- [Setup](#setup)
    - [Prerequisites](#prerequisites)
    - [Installation](#installation)
    - [Integration](#integration)
        - [Required Classes](#required-classes)
            - [Router](#router)
            - [ConfigProvider](#configprovider)
        - [Conditionally Required](#conditionally-required)
            - [StorageProvider](#storageprovider)
        - [Optional](#optional)
            - [EncryptionProvider](#encryptionprovider)
            - [SecureStorageProvider](#securestorageprovider)
- [Implementation Details](#implementation-details)
    - [Authorization Code Grant](#authorization-code-grant)
    - [Device Code Grant](#device-code-grant)
    - [Refresh Token Grant](#refresh-token-grant)
    - [Logout/Disconnect](#logoutdisconnect)
- [Documentation](#documentation)
- [Contributing](#contributing)
- [License](#license)

Background
----------

[](#background)

The [NPR One API](https://dev.npr.org/api/) provides a lightweight [REST](https://www.restapitutorial.com/)/[Hypermedia](https://smartbear.com/learn/api-design/what-is-hypermedia/) interface to power an [NPR One](https://www.npr.org/about/products/npr-one/) experience. To secure our API, we have implemented an authorization server based on the [OAuth 2.0 protocol](https://tools.ietf.org/html/rfc6749), a well-accepted Internet standard.

Third-party developers have two primary methods for obtaining the access tokens required by our API to interact with any of our other micro-services:

- the `authorization_code` grant
- the `device_code` grant (a custom grant based on Google's proposed spec for [OAuth2 for Limited Input Devices](https://developers.google.com/identity/protocols/OAuth2ForDevices))

The NPR One authorization server does **not** currently accept the `implicit` grant type described in the OAuth2 spec due to security concerns.

Both the `device_code` and `authorization_code` grant types require an OAuth2 `client_secret` to generate an access token. However, since the source code for web applications written in a client-side language (like Javascript) cannot be kept private, a server-side proxy is required to safely make calls to the authorization server and ensure the security of your OAuth2 credentials.

In order to make this requirement less painful for third-party developers, we are providing this PHP-based proxy as an open-source package to help you get up-and-running quickly and prevent NPR One client credentials from being compromised in public source code.

Setup
-----

[](#setup)

This project is designed to be executed in a server environment with [Apache HTTP Server](https://httpd.apache.org/) or [Nginx](https://www.nginx.com/).

### Prerequisites

[](#prerequisites)

A recent version of [PHP](https://php.net/), equal to or greater than 7.3.0 is required.

The default [EncryptionProvider](/src/Providers/EncryptionProvider.php) class provided in this package relies on the [OpenSSL](https://php.net/manual/en/book.openssl.php) extension. If OpenSSL is unavailable, the consumer has the option to implement a custom EncryptionProvider class that implements our [EncryptionInterface](/src/Interfaces/EncryptionInterface.php). (For more information, see the [EncryptionProvider](#encryptionprovider) section.)

Usage of NPR's authorization server requires a registered developer account with the [NPR One Developer Center](https://dev.npr.org/). If you do not already have a Dev Center account, you can [register for a personal account](https://dev.npr.org/apply/) and get started immediately.

### Installation

[](#installation)

This project is intended to be run as a sub-module (or dependency) of a larger project and should be installed using [Composer](https://getcomposer.org/) (an open-source dependency manager for PHP projects):

```
[sudo] composer install npr/npr-one-backend-proxy

```

If you do not already have a Composer project set up, you can start one quickly with:

```
composer init --require="npr/npr-one-backend-proxy" -n

```

### Integration

[](#integration)

The following 2 PHP classes must be created to integrate this package into your project:

- [Router](#router)
- [ConfigProvider](#configprovider)

Additionally, if you are using the `authorization_code` grant, a [StorageProvider](#storageprovider) class will be required. Examples of each can be found in the [examples](/examples/) folder.

#### Required Classes

[](#required-classes)

##### Router

[](#router)

Create a router which calls the relevant public methods in *either* [AuthCodeController](/src/Controllers/AuthCodeController.php) *or* [DeviceCodeController](/src/Controllers/DeviceCodeController.php), depending on which grant type will be used (`authorization_code` or `device_code`, respectively).

All consumers, regardless of grant type, **MUST** implement a route that maps to the `generateNewAccessTokenFromRefreshToken()` function in the [RefreshTokenController](/src/Controllers/RefreshTokenController.php) class. This route allows your server to seamlessly request a new access token when the original one has expired. If you do not implement this route, your users will automatically be logged out after 2 weeks and required to log back in to resume listening, which is not the desired user experience.

Similarly, all consumers (assuming they provide some kind of 'Logout' or 'Disconnect from NPR One' functionality) **SHOULD** implement a route that maps to the `deleteAccessAndRefreshTokens()` function in the [LogoutController](/src/Controllers/LogoutController.php) class. This route allows your app to ensure that all persistent data related to a logged-in state (such as access tokens and refresh tokens) are removed from NPR's authorization server, as well as ensuring that the `refresh_token` is removed from the secure storage layer. This function takes in an access token ***but*** it can also work without any input, assuming that refresh tokens are being stored persistently in the secure storage layer.

The [Router.php](/examples/Router.php) file in the [examples](/examples/) folder provides a hypothetical [Laravel](https://laravel.com/)-esque example of what this might look like. Please note, this code is intended only as an example to provide guidance on how to get started and has not been tested. This example includes code for both the `authorization_code` and `device_code` grant types, but in your actual implementation, include only the code relevant to whichever grant type you are using in your application.

##### ConfigProvider

[](#configprovider)

Create a ConfigProvider class that implements our [ConfigInterface](/src/Interfaces/ConfigInterface.php) to power your controller classes. The ConfigProvider class will encapsulate the consumer-specific variables (your client ID and client secret) needed to power this OAuth2 proxy.

There is a sample [ConfigProvider.php](/examples/ConfigProvider.php) in the [examples](/examples/) folder to help you get started. This class does not need to be complicated and can mostly just return hard-coded strings. **However**, do not include your client secret (or your encryption salt) in any files that will appear in public repositories, as this could compromise your application. We assume that you either plan to keep your code private or you have some form of private secrets file that is not included in any public repositories or publicly-accessible locations.

#### Conditionally Required

[](#conditionally-required)

##### StorageProvider

[](#storageprovider)

If you are using the `authorization_code` grant (and thereby the `AuthCodeController`), create a StorageProvider class which implements our [StorageInterface](/src/Interfaces/StorageInterface.php). The StorageProvider is required to validate the OAuth2 `state` param.

You will find a sample [StorageProvider.php](/examples/StorageProvider.php) file in the [examples](/examples/) folder. The example utilizes [Predis](https://github.com/nrk/predis), a PHP [Redis](https://redis.io/) client, but there are many other options, including [Memcached](https://php.net/manual/en/book.memcached.php) and [PHP sessions](https://php.net/manual/en/book.session.php). MySQL is also an option, but not recommended because it is likely to be much slower. We picked Predis for demonstration purposes because the syntax is very simple and applicable to many other storage layers.

#### Optional

[](#optional)

##### EncryptionProvider

[](#encryptionprovider)

The Controller classes will save the refresh token and access token in a cookie by default. In order to keep those refresh tokens secure, we encrypt them before saving and decrypt them when we need to retrieve them. To make this process less cumbersome, a default [EncryptionProvider](/src/Providers/EncryptionProvider.php) has been provided. However, this particular EncryptionProvider relies on the [OpenSSL](https://php.net/manual/en/book.openssl.php) extension being available, which may not be an option for all developers. If OpenSSL is unavailable, or if you want to use a different method of encryption, you can use a custom encryption provider that implements our [EncryptionInterface](/src/Interfaces/EncryptionInterface.php).

If you choose to implement a custom encryption provider, use the [default implementation](/src/Providers/EncryptionProvider.php) as your example. The syntax for including your own custom encryption provider is as follows:

`authorization_code` grant type:

```
use NPR\One\Controllers\AuthCodeController;
use Your\Package\Here\ConfigProvider;
use Your\Package\Here\EncryptionProvider;
use Your\Package\Here\StorageProvider;

$controller = (new AuthCodeController())
        ->setConfigProvider(new ConfigProvider())
        ->setStorageProvider(new StorageProvider())
        ->setEncryptionProvider(new EncryptionProvider());
```

`device_code` grant type:

```
use NPR\One\Controllers\DeviceCodeController;
use Your\Package\Here\ConfigProvider;
use Your\Package\Here\EncryptionProvider;

$controller = (new DeviceCodeController())
        ->setConfigProvider(new ConfigProvider())
        ->setEncryptionProvider(new EncryptionProvider());
```

##### SecureStorageProvider

[](#securestorageprovider)

As explained above, encrypted cookies are used to store refresh tokens across sessions. However, cookies are not the only possible storage method: [Redis](https://redis.io/) and [Memcached](https://php.net/manual/en/book.memcached.php) are good options (as long as you have a mechanism for identifying the user across sessions, which may still require cookies). If you are considering using PHP's session storage, you may want to take a look at [PHP-Secure-Session](https://github.com/ezimuel/PHP-Secure-Session), which provides an extra layer of security through encryption.

All of the Controller classes are configured to use the [SecureCookieProvider](/src/Providers/SecureCookieProvider.php) as the default secure storage layer, but you can easily override this using the `setSecureStorageProvider()` function:

`authorization_code` grant type:

```
use NPR\One\Controllers\AuthCodeController;
use Your\Package\Here\ConfigProvider;
use Your\Package\Here\SecureStorageProvider;
use Your\Package\Here\StorageProvider;

$controller = (new AuthCodeController())
        ->setConfigProvider(new ConfigProvider())
        ->setStorageProvider(new StorageProvider())
        ->setSecureStorageProvider(new SecureStorageProvider());
```

`device_code` grant type:

```
use NPR\One\Controllers\DeviceCodeController;
use Your\Package\Here\ConfigProvider;
use Your\Package\Here\SecureStorageProvider;

$controller = (new DeviceCodeController())
        ->setConfigProvider(new ConfigProvider())
        ->setSecureStorageProvider(new SecureStorageProvider());
```

Your custom secure storage provider class needs to implement the [StorageInterface](/src/Interfaces/StorageInterface.php), but aside from that there are no special requirements. If you are using a tool like Redis or Memcached, you are not required to encrypt or decrypt your tokens since those systems are typically already implicitly secure. Encryption is only explicitly required by the [SecureCookieProvider](/src/Providers/SecureCookieProvider.php) class.

Implementation Details
----------------------

[](#implementation-details)

Read on for more information about how this package operates behind-the-scenes, which will help guide how your client application interacts with this backend proxy.

### Authorization Code Grant

[](#authorization-code-grant)

The `authorization_code` flow has two phases, which in our case correspond to the `startAuthorizationGrant()` and `completeAuthorizationGrant()` functions in the [AuthCodeController](/src/Controllers/AuthCodeController.php) class:

- **Phase 1:** `startAuthorizationGrant()` constructs the query parameters that are needed for the call and appends them to `https://authorization.api.npr.org/v2/authorize`. Your router should then redirect the browser to that URL (either using a framework's built-in function such as Laravel's `redirect()->away($url)`, or otherwise just using a good old-fashioned `header("Location: $url")`).
- **Phase 2:** `completeAuthorizationGrant()` should be mapped to the `redirect_uri` that you added to your client application in the NPR One [Developer Console](https://dev.npr.org/console). This function has two primary responsibilities:

    1. Validating the `state` parameter that was generated during the `startAuthorizationGrant()` phase. This extra check ensures that your call was not intercepted by a malicious third party.
    2. Exchanging the authorization code for an actual access token using the `POST https://authorization.api.npr.org/v2/token` endpoint.

It then saves the token to an unencrypted cookie called `access_token` using our [CookieProvider](/src/Providers/CookieProvider.php) class. **NOTE:** it is *highly* recommended that your client application retrieves the value of the cookie, stores it somewhere locally (HTML5 [localStorage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) is a good option), and then **deletes** the cookie. Otherwise, since the cookie is not encrypted it is not considered secure, and may also result in extra overhead on subsequent HTTP requests.

Note that the `completeAuthorizationGrant()` function does return an [AccessTokenModel](/src/Models/AccessTokenModel.php), but since the `authorization_code` grant is designed to work by redirecting the browser, it is not recommended that you actually return JSON from this endpoint. Instead, you will want to use the `getRedirectUri()` function to return to your client application and then retrieve the access token from the cookie as described above.

### Device Code Grant

[](#device-code-grant)

The `device_code` grant similarly has two phases, but requires a little more work on the part of the client. The [DeviceCodeController](/src/Controllers/DeviceCodeController.php) class has two public methods: `startDeviceCodeGrant()` and `pollDeviceCodeGrant()`; each should be mapped to a unique endpoint in your router.

- **Phase 1:** The client starts off the process by calling the route that corresponds to the `startDeviceCodeGrant()` function, which calls the `POST https://authorization.api.npr.org/v2/device` endpoint and then does two things: one, it safely stores the `device_code` (value) itself, either in an encrypted cookie or using a custom secure storage provider as described [here](#securestorageprovider); and secondly, it returns *everything else* as a JSON object to the consumer. The consumer is then responsible for displaying the `user_code` and `verification_uri` on the screen.
- **Phase 2:** Next, the client is responsible for **polling** the route that corresponds to the `pollDeviceCodeGrant()` function, which calls the `POST https://authorization.api.npr.org/v2/token` endpoint with the securely-stored `device_code` and checks to see whether the user has logged in yet (returning an access token if so, and throwing an Exception if not). This polling should occur at a rate not exceeding the `interval` value in the JSON object returned by the previous call.

All device code/user code pairs will expire within the `expires_in` value in the JSON object returned by the previous call (this value represents a TTL in seconds). The client application is responsible for calling the route that corresponds to the `startDeviceCodeGrant()` function to restart this process if the user fails to log in before the device code expires.

### Refresh Token Grant

[](#refresh-token-grant)

The `refresh_token` that is generated in association with every new access token should be stored securely either in an encrypted cookie or by using a custom secure storage provider as described [here](#securestorageprovider). The [RefreshTokenController](/src/Controllers/RefreshTokenController.php) class is thus refreshingly simple and has one method:

- `generateNewAccessTokenFromRefreshToken()` looks for this `refresh_token` in the secure storage provider and (if found) uses the `refresh_token` grant provided by the `POST https://authorization.api.npr.org/v2/token` endpoint to obtain a new access token for the user. (And in case you were wondering: yes, that call will result in a new `refresh_token` being generated, which is then saved to the secure storage layer in the exact same way.)

This method should be called when any client application that has previously obtained a valid access token suddenly receives a `401 Unauthorized` response from any of our micro-services, indicating that the access token has expired. This error should call the endpoint in your router that calls `generateNewAccessTokenFromRefreshToken()`. A new access token will be generated and returned as raw JSON (where it is up to the client application to store it securely). If a new access token could not be generated, the client may retry the call up to 2-3 times, but after that point the user should be considered logged out and prompted to log in again.

**Optional implementation:** The [AccessTokenModel](/src/Models/AccessTokenModel.php) and the corresponding JSON output do include an `expires_in` value (TTL in seconds) for the access token, so the client application *may* choose (but is not required) to call the route corresponding to `generateNewAccessTokenFromRefreshToken()` before the token actually expires, *or* after it was set to expire but before another API call is attempted. Note that regardless of whether it had already expired or not, the original access token **will** be deleted immediately as part of that call.

### Logout/Disconnect

[](#logoutdisconnect)

We ask all clients to help secure user data and free up unused resources in our system by implementing a form of logout functionality that will revoke the user’s previously-generated access tokens and refresh tokens through the `POST https://authorization.api.npr.org/v2/token/revoke` endpoint. The `deleteAccessAndRefreshTokens()` function in the [LogoutController](/src/Controllers/LogoutController.php) class will perform this task, in addition to deleting the `refresh_token` that was previously saved to an encrypted cookie or your custom [secure storage provider](#securestorageprovider). Your client application can be ignorant of whatever mechanism you're using to securely store the refresh token and safely assume that it is properly removed as part of logout.

As described in the [NPR One API Reference](https://dev.npr.org/api), the `POST https://authorization.api.npr.org/v2/token/revoke` endpoint takes in either an access token or a refresh token. By default, it's assumed to be an access token, but it will delete **both** regardless of which of the two is passed in. Therefore, the `deleteAccessAndRefreshTokens()` function *can* take in an access token, but if none is provided, it will look for a refresh token and, if found, use that to revoke the pair of tokens. It is recommended to pass in the access token if you have it (especially for client applications developed prior to summer 2016, when refresh tokens were first introduced). If you are certain that refresh tokens have been issued for all your users and there is no chance that they have been removed by other client-side code, you can safely call `deleteAccessAndRefreshTokens()` without any parameters.

This proxy does not impose any requirements for how you set up and call your endpoints (save for what is strictly required by the OAuth 2.0 spec), so the access token parameter needed for the `deleteAccessAndRefreshTokens()` function can be obtained from a variety of sources: via a query parameter, form `POST` data, a `POST` with a JSON body, and potentially even a cookie, if that is how you are storing your access tokens client-side. The example [Router.php](/examples/Router.php) file uses a query parameter for simplicity's sake. In most cases, `POST` requests with form data or JSON bodies are preferable because they are slightly harder to intercept over insecure networks, but since the assumption here is that the access token will be revoked almost immediately, keeping the token secure is not a huge concern.

Documentation
-------------

[](#documentation)

Further information about the public API of this package can be found in the [docs](/docs/#readme) folder.

For background information about the NPR One API and our use of OAuth2, please see the [developer guide](https://dev.npr.org/guide/) at the [NPR One Developer Center](https://dev.npr.org/). In particular, the section on the [Authorization Service](https://dev.npr.org/guide/services/authorization/) may be of interest.

Contributing
------------

[](#contributing)

If you're interested in contributing to this project by submitting bug reports, helping to improve the documentation, or writing actual code, please read [our contribution guidelines](/CONTRIBUTING.md).

License
-------

[](#license)

Copyright (c) 2016 NPR

Licensed under the [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0) (the “License”) with the following modification; You may not use this file except in compliance with the License as modified by the addition of Section 10, as follows:

##### 10. Additional Prohibitions

[](#10-additional-prohibitions)

When using the Work, You may not (or allow those acting on Your behalf to):

a. Perform any action with the intent of introducing to the Work, the NPR One API, the NPR servers or network infrastructure, or any NPR products and services any viruses, worms, defects, Trojan horses, malware or any items of a destructive or malicious nature; or obtaining unauthorized access to the NPR One API, the NPR servers or network infrastructure, or any NPR products or services;

b. Remove, obscure or alter any NPR terms of service, including the [NPR services Terms of Use](https://www.npr.org/about-npr/179876898/terms-of-use) and the [Developer API Terms of Use](https://dev.npr.org/terms-of-use/), or any links to or notices of those terms; or

c. Take any other action prohibited by any NPR terms of service, including the [NPR services Terms of Use](https://www.npr.org/about-npr/179876898/terms-of-use) and the [Developer API Terms of Use](https://dev.npr.org/terms-of-use/).

You may obtain a copy of the License at

Unless required by applicable law or agreed to in writing, software distributed under the License with the above modification is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

###  Health Score

39

—

LowBetter than 85% of packages

Maintenance33

Infrequent updates — may be unmaintained

Popularity24

Limited adoption so far

Community22

Small or concentrated contributor base

Maturity68

Established project with proven stability

 Bus Factor1

Top contributor holds 50% 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 ~178 days

Recently: every ~24 days

Total

15

Last Release

1154d ago

Major Versions

1.1.2 → 2.0.02018-09-27

2.0.0 → v3.1.12020-02-18

v3.1.2 → v4.0.02021-03-09

PHP version history (4 changes)1.0.0PHP &gt;=5.5.0

2.0.0PHP &gt;=5.6.0

v3.1.1PHP &gt;=7.2.0

v4.0.0PHP &gt;=7.3.0

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/332099?v=4)[NPR](/maintainers/npr)[@npr](https://github.com/npr)

![](https://avatars.githubusercontent.com/u/855115?v=4)[Nara Kasbergen Kwon](/maintainers/xiehan)[@xiehan](https://github.com/xiehan)

![](https://www.gravatar.com/avatar/65f71b954b6177e90a4bb23751a8d3e71e006cfff996fd439a334afa7d784211?d=identicon)[npr\_river](/maintainers/npr_river)

---

Top Contributors

[![xiehan](https://avatars.githubusercontent.com/u/855115?v=4)](https://github.com/xiehan "xiehan (19 commits)")[![jaredbiehler](https://avatars.githubusercontent.com/u/684719?v=4)](https://github.com/jaredbiehler "jaredbiehler (10 commits)")[![aunt-kitty-codes](https://avatars.githubusercontent.com/u/35381754?v=4)](https://github.com/aunt-kitty-codes "aunt-kitty-codes (7 commits)")[![NoahCarnahan](https://avatars.githubusercontent.com/u/2117127?v=4)](https://github.com/NoahCarnahan "NoahCarnahan (1 commits)")[![schersh](https://avatars.githubusercontent.com/u/13408456?v=4)](https://github.com/schersh "schersh (1 commits)")

---

Tags

nproauthoauth-clientoauth-proxyrefresh-tokensproxyoauthoauth2npr

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/npr-npr-one-backend-proxy/health.svg)

```
[![Health](https://phpackages.com/badges/npr-npr-one-backend-proxy/health.svg)](https://phpackages.com/packages/npr-npr-one-backend-proxy)
```

###  Alternatives

[league/oauth2-client

OAuth 2.0 Client Library

3.8k125.2M1.3k](/packages/league-oauth2-client)[google/auth

Google Auth Library for PHP

1.4k286.7M205](/packages/google-auth)[overtrue/socialite

A collection of OAuth 2 packages.

1.4k5.6M90](/packages/overtrue-socialite)[ellaisys/aws-cognito

AWS Cognito package that allows Auth and other related features using the AWS SDK for PHP

121242.9k1](/packages/ellaisys-aws-cognito)[simplesamlphp/simplesamlphp-module-oidc

A SimpleSAMLphp module adding support for the OpenID Connect protocol

5017.7k1](/packages/simplesamlphp-simplesamlphp-module-oidc)[chervand/yii2-oauth2-server

OAuth 2.0 server for Yii 2.0 with MAC tokens support.

1524.5k1](/packages/chervand-yii2-oauth2-server)

PHPackages © 2026

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