pipasolutions/openid-client

OpenID Connect Client Library for PiPA

dev-master 2020-06-05 00:20 UTC

This package is auto-updated.

Last update: 2024-04-18 21:02:39 UTC


README

This package provides PiPA OpenID support, using the PHP League's OAuth 2.0 Client and lcobocci's jwt library.

Requirements

The following versions of PHP are supported.

  • PHP 5.6+
  • PHP 7.1+

The following mods must also be enabled:

  • php-mbstring
  • php-xml
  • php-openssl

Installation

To install, the recommended way is to use composer and the pipa repository to your composer file.

composer require pipasolutions/openid-client-php

On PHP 5.* an additional step is required because the random_bytes function isn't supplied by the core library. To fix this, run the following:

composer require "paragonie/random_compat" ">=1 <9.99"

Usage

The usage follows the OpenID Connect/OAuth2 standards. Please see the OpenID Connect docs and OAuth2 docs for more information.

Before you will be able to use the client to authenticate, you need to register for a client id and secret. Contact PiPA for more information and to have a client id and secret provisioned.

How you store client_id and client_secret is your choice, but it is not recommended to store them in source code. Rather, they (and the client_secret in particular) should be loaded from a (secured) configuration file or secret management system.

Performing an authentication request:

You have to initialize the PiPAOpenId class.

use PiPASolutions\OpenId\PiPAOpenId;

...

$clientId = $secured_credentials['client_id'];
$clientSecret = $secured_credentials['client_secret'];

$oauthServerPath = 'https://path.to/server/'
$redirectUrl = 'https://this.server/login/redirect'

$this->openid = new PiPAOpenId($clientId, $clientSecret, $redirecturl, $oauthServerPath);

Important: Make sure the oauthServerPath is https. If it is http and redirects the client may fail to authenticate.

oauthServerPath and redirectUrl are as described above. clientId and clientSecret will either be provided by PiPA or are the result of the call clientRegistration call made previously and persisted.

To initiate the login process:

$this->openid->startAuth();

This call also has the optional parameters as follow:

  1. user id (string) - a hint about the user id which when provided will only allow that user login
  2. scopes (array) - list of scopes to request access to
  3. force pairing (boolean) - if true, will force pairing rather than allowing an authentication request. Only use if needed, directing users to pipa.co/pair instead is recommended

You must also implement the handler for the callback URL you define in $redirectUrl. Use the following in the callback:

$tokens = $this->openid->getTokens($state, $code);

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

$tokens.getUserId() will give you a unique identifier for the user; this can be used in your database to represent the user and should be checked against in subsequent logins.

The rest of the methods may not be important to you if you are simply performing a login. They give various tokens; the access token can be used to request data from the server, the refresh token can be used to get another access token, and the access token expires after a certain length of time. The OpenID and OAuth documentation explain this more fully.

The userID returned from $tokens.getUserId() can optionally be used in $this->openid->startAuth(userId) when initiating the login; instead of accepting any PiPA authentication, it would require a particular user to authenticate.

Eventually, this provider will be extended so as to allow for more complex interactions with the server including getting more data about the user.

Requesting an email address

To request an email address from the user, you must specify the email scope when you call openid->startAuth() - this will look something like:

$openid->startAuth(null, [PiPAOpenIdConstants::SCOPE_EMAIL]);

When this is specified, the user will be prompted to provide an email, but may opt not to. It is up to the implementer to decide whether to accept the authentication anyways in this case or to refuse it.

To retrieve the email address, get the Id Token from the token array using getIdToken(), which returns a Token object.

$tokens = $this->openid->getTokens($state, $code);
$idToken = $tokens->getIdToken();
if ($idToken->hasClaim(PiPAOpenIdConstants::CLAIM_EMAIL)) {
  $email = $idToken->getClaim(PiPAOpenIdConstants::CLAIM_EMAIL);
  // handle receiving email
} else {
  // handle not receiving email
}

Testing

NOT IMPLEMENTED YET!

$ ./vendor/bin/phpunit

License

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