oliverschloebe/oauth2-steadyhq

Steady OAuth 2.0 package for the PHP League's OAuth 2.0 Client

1.0.0 2023-06-21 21:42 UTC

This package is auto-updated.

Last update: 2024-04-25 12:29:18 UTC


README

This package provides Steady OAuth 2.0 support for the PHP League's OAuth 2.0 Client.

StyleCI License Latest Stable Version Latest Version Source Code

Installation

composer require oliverschloebe/oauth2-steadyhq

Steady API

https://developers.steadyhq.com/#oauth-2-0

Usage

Register your apps on steadyhq.com to get clientId and clientSecret.

OAuth2 Authentication Flow

require_once __DIR__ . '/vendor/autoload.php';

//session_start(); // optional, depending on your used data store

$steadyProvider = new \OliverSchloebe\OAuth2\Client\Provider\Steady([
	'clientId'	=> 'yourId',          // The client ID of your Steady app
	'clientSecret'	=> 'yourSecret',      // The client password of your Steady app
	'redirectUri'	=> 'yourRedirectUri'  // The return URL you specified for your app on Steady
]);

// Get authorization code
if (!isset($_GET['code'])) {
	// Options are optional, scope defaults to ['read']
	$options = [ 'scope' => ['read'] ];
	// Get authorization URL
	$authorizationUrl = $steadyProvider->getAuthorizationUrl($options);

	// Get state and store it to the session
	$_SESSION['oauth2state'] = $steadyProvider->getState();

	// Redirect user to authorization URL
	header('Location: ' . $authorizationUrl);
	exit;
} elseif (empty($_GET['state']) || (isset($_SESSION['oauth2state']) && $_GET['state'] !== $_SESSION['oauth2state'])) { // Check for errors
	if (isset($_SESSION['oauth2state'])) {
		unset($_SESSION['oauth2state']);
	}
	exit('Invalid state');
} else {
	// Get access token
	try {
		$accessToken = $steadyProvider->getAccessToken(
			'authorization_code',
			[
				'code' => $_GET['code']
			]
		);
		
		// We have an access token, which we may use in authenticated
		// requests against the Steady API.
		echo 'Access Token: ' . $accessToken->getToken() . "<br />";
		echo 'Refresh Token: ' . $accessToken->getRefreshToken() . "<br />";
		echo 'Expired in: ' . $accessToken->getExpires() . "<br />";
		echo 'Already expired? ' . ($accessToken->hasExpired() ? 'expired' : 'not expired') . "<br />";
	} catch (\League\OAuth2\Client\Provider\Exception\IdentityProviderException $e) {
		exit($e->getMessage());
	}

	// Get resource owner
	try {
		$resourceOwner = $steadyProvider->getResourceOwner($accessToken);
	} catch (\League\OAuth2\Client\Provider\Exception\IdentityProviderException $e) {
		exit($e->getMessage());
	}
        
	// Store the results to session or whatever
	$_SESSION['accessToken'] = $accessToken;
	$_SESSION['resourceOwner'] = $resourceOwner;
    
	var_dump(
		$resourceOwner->getId(),
		$resourceOwner->getName(),
		$resourceOwner->getEmail(),
		$resourceOwner->getAttribute('email'), // allows dot notation, e.g. $resourceOwner->getAttribute('group.field')
		$resourceOwner->toArray()
	);
}

Refreshing a Token

Once your application is authorized, you can refresh an expired token using a refresh token rather than going through the entire process of obtaining a brand new token. To do so, simply reuse this refresh token from your data store to request a refresh.

$steadyProvider = new \OliverSchloebe\OAuth2\Client\Provider\Steady([
	'clientId'	=> 'yourId',          // The client ID of your Steady app
	'clientSecret'	=> 'yourSecret',      // The client password of your Steady app
	'redirectUri'	=> 'yourRedirectUri'  // The return URL you specified for your app on Steady
]);

$existingAccessToken = getAccessTokenFromYourDataStore();

if ($existingAccessToken->hasExpired()) {
	$newAccessToken = $steadyProvider->getAccessToken('refresh_token', [
		'refresh_token' => $existingAccessToken->getRefreshToken()
	]);

	// Purge old access token and store new access token to your data store.
}

Sending authenticated API requests

The Steady OAuth 2.0 provider provides a way to get an authenticated API request for the service, using the access token; it returns an object conforming to Psr\Http\Message\RequestInterface.

$mySubscriptionsRequest = $steadyProvider->getAuthenticatedRequest(
	'GET',
	'https://steadyhq.com/api/v1/subscriptions/me', // see https://developers.steadyhq.com/#current-subscription
	$accessToken
);

// Get parsed response of current authenticated user's subscriptions; returns array|mixed
$mySubscriptions = $steadyProvider->getParsedResponse($mySubscriptionsRequest);

var_dump($mySubscriptions);

Sending non-authenticated API requests

Send a non-authenticated API request to public endpoints of the Steady API; it returns an object conforming to Psr\Http\Message\RequestInterface.

$httpClient = new \GuzzleHttp\Client([
	'headers' => [
		'X-Api-Key' => '<Your REST API Key>',
	],
]);

$steadyProvider = new Steady([
	// Your client options here (clientId, clientSecret etc)
], [
	'httpClient' => $httpClient
]);

$subscriptionsParams = [ 'filter[subscriber][email]' => 'alice@example.com' ];
$subscriptionsRequest = $steadyProvider->getRequest(
	'GET',
	'https://steadyhq.com/api/v1/subscriptions?' . http_build_query($subscriptionsParams)
);

// Get parsed response of non-authenticated API request; returns array|mixed
$subscriptions = $steadyProvider->getParsedResponse($subscriptionsRequest);

var_dump($subscriptions);

Using a proxy

It is possible to use a proxy to debug HTTP calls made to Steady. All you need to do is set the proxy and verify options when creating your Steady OAuth2 instance. Make sure to enable SSL proxying in your proxy.

$steadyProvider = new \OliverSchloebe\OAuth2\Client\Provider\Steady([
	'clientId'	=> 'yourId',          // The client ID of your Steady app
	'clientSecret'	=> 'yourSecret',      // The client password of your Steady app
	'redirectUri'	=> 'yourRedirectUri'  // The return URL you specified for your app on Steady
	'proxy'		=> '192.168.0.1:8888',
	'verify'	=> false
]);

Requirements

PHP 8.0 or higher.

Testing

$ ./vendor/bin/parallel-lint src test
$ ./vendor/bin/phpunit --coverage-text
$ ./vendor/bin/phpcs src --standard=psr2 -sp

License

The MIT License (MIT). Please see License File for more information.