Skip to content

Feature/client access tokens #9

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/).

## 2.0.0 - 2025-07-27
### Added
- Added support for authentication via client access tokens
### Removed
- Removed support for authentication via JWT tokens

## 1.6.2 - 2025-04-04
### Added
- Added an optional "destination" parameter to the authUrl, to facilitate automatically updating tokens.
Expand Down
29 changes: 2 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,38 +16,13 @@ use statikbe\udb\EntryAPI;
use statikbe\udb\Environments;

$udb = new EntryAPI(
getenv("UDB_KEY"), // API key
getenv("UDB_CLIENT_ID"), // Client ID
getenv("UDB_CLIENT_SECRET"), // Client Secret
'/var/www/path/to/your/jwt/token.json', // Path to where you're JWT token will be stored
Environments::PROD // The package includes an enum for that sets endpoints based in environment
);

`````


## Authentication

To authenticate with UDB, you'll need a JWT token. The url from which you get that token can be generate with the following command:

````php
$url = $udb->api->generalJwtUrl();
echo $url;
exit;
````

The code above will echo a URL. Paste that URL in a browser window, then you'll be prompted to log in with your UiT-ID.
After logging in you'll see a blank screen with "An internal server error occurred".

**You can find the access token and the refresh token in the url of that page.**

Save both tokens in the json file the specified above, formatted like this:

````json
{
"accessToken": "",
"refreshToken": ""
}
````

## Usage

Once you've authenticated with the API, you can use the following functions:
Expand Down
5 changes: 3 additions & 2 deletions src/EntryAPI.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@ class EntryAPI

public ApiService $api;

public function __construct(string $apiKey, string $storagePath, $environment = Environments::PROD)
public function __construct(string $clientId, $clientSecret, string $storagePath, $environment = Environments::PROD)
{
// check if storage path exists & is writable, throw exception if not
$this->api = new ApiService(
$apiKey,
$clientId,
$clientSecret,
$storagePath,
$environment
);
Expand Down
8 changes: 4 additions & 4 deletions src/Environments.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ enum Environments
case TEST;

case PROD;

public function getJWTUrl(): string
public function getOAuthUrl(): string
{
return match ($this) {
self::TEST => 'https://jwt-test.uitdatabank.be',
self::PROD => 'https://jwt.uitdatabank.be',
self::TEST => 'https://account-test.uitid.be',
self::PROD => 'https://account.uitid.be',
};
}

Expand Down
10 changes: 5 additions & 5 deletions src/services/entry/ApiService.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ class ApiService extends AuthService

private Environments $environment;

public function __construct($apiKey, $storagePath, Environments $environment)
public function __construct($clientId, $clientSecret, $storagePath, Environments $environment)
{
parent::__construct($apiKey, $storagePath, $environment);
$this->apiKey = $apiKey;
parent::__construct($clientId, $clientSecret, $storagePath, $environment);
$this->clientId = $clientId;
$this->clientSecret = $clientSecret;
$this->environment = $environment;
$this->endpoint = $environment->getEndpoint();
$this->authUrl = $environment->getOAuthUrl();
$this->accessToken = $this->getAccessToken();
}

Expand All @@ -38,7 +40,6 @@ public function post($data, $endPoint, $method = "POST", $headers = [], $baseUrl
$tries++;
$headers = array_merge($headers, [
"Authorization" => "Bearer {$this->getAccessToken()}",
"X-Api-Key" => $this->apiKey,
]);
try {
$request = new Request(
Expand Down Expand Up @@ -140,7 +141,6 @@ public function get($path, $parameters = [])

$headers = [
"Authorization" => "Bearer {$this->getAccessToken()}",
"X-Api-Key" => $this->apiKey,
];

$request = new Request(
Expand Down
59 changes: 27 additions & 32 deletions src/services/entry/AuthService.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,23 @@
namespace statikbe\udb\services\entry;

use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Request;
use statikbe\udb\Environments;

class AuthService
{
protected $apiKey;

private $jwtUrl;
protected $clientId;
protected $clientSecret;
protected $authUrl;

private $storagePath;
private Environments $environment;


public function __construct($apiKey, $storagePath, Environments $environment)
public function __construct($clientId, $clientSecret, $storagePath, Environments $environment)
{
$this->apiKey = $apiKey;
$this->jwtUrl = $environment->getJWTUrl();

$this->authUrl = $environment->getOAuthUrl();
$this->storagePath = $storagePath;
$this->environment = $environment;
}
Expand All @@ -32,39 +32,37 @@ public function getAccessToken(): string|null
$this->storagePath
);
$credentials = json_decode($file, true);
return $credentials['accessToken'];
if(!$credentials || !isset($credentials['access_token'])) {
$this->refreshAccessToken();
$file = file_get_contents($this->storagePath); // Re-read the updated token file
$credentials = json_decode($file, true);
}
return $credentials['access_token'];
}
} catch (\Exception $e) {
throw $e;
}
return null;
}

/** Use this function the first time to create your tokens.
* And manually save them in /data/udb-tokens/credentials.json
*
* Use the destination parameter to set the redirect URL.
*
* {
* "accessToken":"access_token_from_url",
* "refreshToken":"refresh_token_from_url",
* }
*/
public function generalJwtUrl($destination = "oob"): string
{
return $this->jwtUrl . '/connect?apiKey=' . $this->apiKey . "&destination={$destination}";
}

public function refreshAccessToken(): void
{
try {
$requestUrl = $this->jwtUrl . '/refresh?apiKey=' . $this->apiKey . '&refresh=' . $this->getRefreshToken();
$url = $this->authUrl . "/realms/uitid/protocol/openid-connect/token";
$client = new Client();
$response = $client->get($requestUrl);
$accessToken = $response->getBody()->getContents();
$this->updateAccessToken($accessToken);

$request = new Request(
"POST",
$url,
[
"Content-Type" => "application/x-www-form-urlencoded",
],
"grant_type=client_credentials&client_id={$this->clientId}&client_secret={$this->clientSecret}");

$response = $client->send($request);
$body = $response->getBody()->getContents();
$this->updateAccessToken($body);
} catch (\Exception $e) {
dd($e);
throw $e;
}
}
Expand All @@ -87,19 +85,16 @@ private function getRefreshToken(): string|null
return null;
}

private function updateAccessToken($accessToken): void
private function updateAccessToken($body): void
{
try {
if (file_exists($this->storagePath)) {
$file = file_get_contents(
$this->storagePath
);
$credentials = json_decode($file, true);
$credentials['accessToken'] = $accessToken;
$fileContents = json_encode($credentials);
file_put_contents(
$this->storagePath,
$fileContents
$body
);
}
} catch (\Exception $e) {
Expand Down