PHPackages                             groton-school/oauth2-blackbaudsky - 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. groton-school/oauth2-blackbaudsky

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

groton-school/oauth2-blackbaudsky
=================================

This package provides Blackbaud SKY OAuth 2.0 support for the PHP League's OAuth 2.0 Client

v0.2.6(2y ago)06451MITPHPCI passing

Since Dec 19Pushed 1mo ago1 watchersCompare

[ Source](https://github.com/groton-school/OAuth2-BlackbaudSKY)[ Packagist](https://packagist.org/packages/groton-school/oauth2-blackbaudsky)[ RSS](/packages/groton-school-oauth2-blackbaudsky/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (3)Versions (10)Used By (1)

> This package was developed to work with data stored in Blackbaud SIS/LMS/SWS instances. We are no longer Blackbaud users, and therefore no longer actively maintaining this package. If you would like to discuss this tool, or the approaches it took to accessing otherwise inaccessible data in Blackbaud, please reach out directly to [Seth Battis](mailto:seth@battis.net?subject=OAuth2-BlackbaudSKY)

Blackbaud SKY API OAuth 2.0 Client
==================================

[](#blackbaud-sky-api-oauth-20-client)

This package provides Blackbaud SKY OAuth 2.0 support for the [PHP League's OAuth 2.0 Client](https://oauth2-client.thephpleague.com/)

See [this example](https://github.com/groton-school/sky-api/tree/main/examples/oauth2) for usage.

[![Version](https://camo.githubusercontent.com/038b8e78af7af376c3fcdbb6211ee0fd1114b05cf6d92d9010522c3cb2be1993/687474703a2f2f706f7365722e707567782e6f72672f67726f746f6e2d7363686f6f6c2f6f61757468322d626c61636b62617564736b792f76657273696f6e)](https://packagist.org/packages/groton-school/oauth2-blackbaudsky)[![License](https://camo.githubusercontent.com/5035f3479647955d1a9d5c1b54de295e76e43789c99d4757d43b29f1e3052fb6/687474703a2f2f706f7365722e707567782e6f72672f67726f746f6e2d7363686f6f6c2f6f61757468322d626c61636b62617564736b792f6c6963656e7365)](https://packagist.org/packages/groton-school/oauth2-blackbaudsky)

---

This package is compliant with [PSR-1](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md), [PSR-2](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md), [PSR-4](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md), and [PSR-7](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-7-http-message.md). If you notice compliance oversights, please send a patch via pull request. If you're interesting in contributing to this library, please take a look at our [contributing guidelines](CONTRIBUTING.md).

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

[](#requirements)

The following versions of PHP are supported.

- PHP 5.6
- PHP 7.0
- PHP 7.1
- PHP 7.2
- PHP 7.3
- PHP 7.4
- PHP 8.0

Usage
-----

[](#usage)

Refer to [this project](https://github.com/groton-school/sky-api/tree/main/examples/oauth2) for example usage.

### Authorization Code Grant

[](#authorization-code-grant)

The following example uses the out-of-the-box `GenericProvider` provided by this library. If you're looking for a specific provider (i.e. Facebook, Google, GitHub, etc.), take a look at our [list of provider client libraries](docs/providers/thirdparty.md). **HINT: You're probably looking for a specific provider.**

The authorization code grant type is the most common grant type used when authenticating users with a third-party service. This grant type utilizes a client (this library), a server (the service provider), and a resource owner (the user with credentials to a protected—or owned—resource) to request access to resources owned by the user. This is often referred to as *3-legged OAuth*, since there are three parties involved.

The following example illustrates this using [Brent Shaffer's](https://github.com/bshaffer) demo OAuth 2.0 application named **Lock'd In**. When running this code, you will be redirected to Lock'd In, where you'll be prompted to authorize the client to make requests to a resource on your behalf.

Now, you don't really have an account on Lock'd In, but for the sake of this example, imagine that you are already logged in on Lock'd In when you are redirected there.

```
$sky = new \GrotonSchool\OAuth2\Client\Provider\BlackbaudSKY([
  BlackbaudSKY::ACCESS_KEY => 'key', // A Blackbaud SKY API subscription access key
  'clientId' => 'demoapp', // The client ID assigned to your app by Blackbaud
  'clientSecret' => 'demopass', // The client password assigned to your app by Blackbaud
  'redirectUri' => 'http://example.com/your-redirect-url/',
]);

// If we don't have an authorization code then get one
if (!isset($_GET['code'])) {
  // Fetch the authorization URL from the provider; this returns the
  // urlAuthorize option and generates and applies any necessary parameters
  // (e.g. state).
  $authorizationUrl = $sky->getAuthorizationUrl();

  // Get the state generated for you and store it to the session.
  $_SESSION['oauth2state'] = $sky->getState();

  // Redirect the user to the authorization URL.
  header('Location: ' . $authorizationUrl);
  exit();

  // Check given state against previously stored one to mitigate CSRF attack
} elseif (
  empty($_GET['state']) ||
  (isset($_SESSION['oauth2state']) &&
    $_GET['state'] !== $_SESSION['oauth2state'])
) {
  if (isset($_SESSION['oauth2state'])) {
    unset($_SESSION['oauth2state']);
  }

  exit('Invalid state');
} else {
  try {
    // Try to get an access token using the authorization code grant.
    $accessToken = $sky->getAccessToken('authorization_code', [
      'code' => $_GET['code'],
    ]);

    // We have an access token, which we may use in authenticated
    // requests against the service provider's API.
    echo 'Access Token: ' . $accessToken->getToken() . '';
    echo 'Refresh Token: ' . $accessToken->getRefreshToken() . '';
    echo 'Expired in: ' . $accessToken->getExpires() . '';
    echo 'Already expired? ' .
      ($accessToken->hasExpired() ? 'expired' : 'not expired') .
      '';

    // The 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.
    $request = $sky->getAuthenticatedRequest(
      'GET',
      'https://api.sky.blackbaud.com/school/v1/academics/departments',
      $accessToken
    );

    // For convenience, the provider also wraps endpoints with a Guzzle client
    $school = $sky->endpoint('school/v1');
    var_export($school->get('levels'));

    // ...and those endpoints can also nest further endpoints
    $academics = $school->endpoint('academics');
    var_export($academics->get('departments'));
  } catch (\League\OAuth2\Client\Provider\Exception\IdentityProviderException $e) {
    // Failed to get the access token or user details.
    exit($e->getMessage());
  }
}
```

### Refreshing a Token

[](#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.

*This example uses [Brent Shaffer's](https://github.com/bshaffer) demo OAuth 2.0 application named **Lock'd In**. See authorization code example above, for more details.*

```
$sky = new \League\OAuth2\Client\Provider\GenericProvider([
  BlackbaudSKY::ACCESS_KEY => 'key', // A Blackbaud SKY API subscription access key
  'clientId' => 'demoapp', // The client ID assigned to your app by Blackbaud
  'clientSecret' => 'demopass', // The client password assigned to your app by Blackbaud
]);

$existingAccessToken = getAccessTokenFromYourDataStore();

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

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

### Using a proxy

[](#using-a-proxy)

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

```
$sky = new \League\OAuth2\Client\Provider\GenericProvider([
    BlackbaudSKY::ACCESS_KEY  => 'key',        // A Blackbaud SKY API subscription access key
    'clientId'                => 'demoapp',    // The client ID assigned to your app by Blackbaud
    'clientSecret'            => 'demopass',   // The client password assigned to your app by Blackbaud
    'redirectUri'             => 'http://example.com/your-redirect-url/'
    'proxy'                   => '192.168.0.1:8888',
    'verify'                  => false
]);
```

Install
-------

[](#install)

Via Composer

```
$ composer require groton-school/oauth2-blackbaudsky
```

License
-------

[](#license)

The MIT License (MIT). Please see [License File](https://github.com/thephpleague/oauth2-client/blob/master/LICENSE) for more information.

###  Health Score

35

—

LowBetter than 77% of packages

Maintenance61

Regular maintenance activity

Popularity13

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity46

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 94.1% 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 ~107 days

Recently: every ~51 days

Total

9

Last Release

845d ago

### Community

Maintainers

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

---

Top Contributors

[![battis](https://avatars.githubusercontent.com/u/419619?v=4)](https://github.com/battis "battis (16 commits)")[![groton-it](https://avatars.githubusercontent.com/u/92397761?v=4)](https://github.com/groton-it "groton-it (1 commits)")

---

Tags

blackbaudoauth2oauth2-clientphpleaguesky-api

### Embed Badge

![Health badge](/badges/groton-school-oauth2-blackbaudsky/health.svg)

```
[![Health](https://phpackages.com/badges/groton-school-oauth2-blackbaudsky/health.svg)](https://phpackages.com/packages/groton-school-oauth2-blackbaudsky)
```

###  Alternatives

[tempest/framework

The PHP framework that gets out of your way.

2.3k37.6k21](/packages/tempest-framework)[civicrm/civicrm-core

Open source constituent relationship management for non-profits, NGOs and advocacy organizations.

762297.9k53](/packages/civicrm-civicrm-core)[neuron-core/neuron-ai

The PHP Agentic Framework.

2.0k832.6k55](/packages/neuron-core-neuron-ai)[xeroapi/xero-php-oauth2

Xero official PHP SDK for oAuth2 generated with OpenAPI spec 3

1074.9M20](/packages/xeroapi-xero-php-oauth2)[tencentcloud/tencentcloud-sdk-php

TencentCloudApi php sdk

3661.3M49](/packages/tencentcloud-tencentcloud-sdk-php)[eslazarev/wildberries-sdk

Wildberries OpenAPI clients (generated).

353.6k](/packages/eslazarev-wildberries-sdk)

PHPackages © 2026

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