PHPackages                             smart-dato/gls-authenticator - 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. smart-dato/gls-authenticator

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

smart-dato/gls-authenticator
============================

Authentication API v2

0.0.1(5mo ago)00[4 PRs](https://github.com/smart-dato/gls-authenticator/pulls)MITPHPPHP ^8.4CI failing

Since Dec 4Pushed 1mo agoCompare

[ Source](https://github.com/smart-dato/gls-authenticator)[ Packagist](https://packagist.org/packages/smart-dato/gls-authenticator)[ Docs](https://github.com/smart-dato/gls-authenticator)[ GitHub Sponsors](https://github.com/SmartDato)[ RSS](/packages/smart-dato-gls-authenticator/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (1)Dependencies (13)Versions (5)Used By (0)

GLS Authentication API v2
=========================

[](#gls-authentication-api-v2)

[![Latest Version on Packagist](https://camo.githubusercontent.com/38b39c2c56a9b03fa25ab06c4bb2dcb341645dec71bd334a2a01db42177555fa/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f736d6172742d6461746f2f676c732d61757468656e74696361746f722e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/smart-dato/gls-authenticator)[![GitHub Tests Action Status](https://camo.githubusercontent.com/dbd7f02d55834b30af3bf2a14412838bfa00019df21bd505e39873d625a8af47/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f736d6172742d6461746f2f676c732d61757468656e74696361746f722f72756e2d74657374732e796d6c3f6272616e63683d6d61696e266c6162656c3d7465737473267374796c653d666c61742d737175617265)](https://github.com/smart-dato/gls-authenticator/actions?query=workflow%3Arun-tests+branch%3Amain)[![GitHub Code Style Action Status](https://camo.githubusercontent.com/70fb3f61aca8cea578bd34a3add9719f4ec7462a281904cd25b8e863cc9c3dd8/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f736d6172742d6461746f2f676c732d61757468656e74696361746f722f6669782d7068702d636f64652d7374796c652d6973737565732e796d6c3f6272616e63683d6d61696e266c6162656c3d636f64652532307374796c65267374796c653d666c61742d737175617265)](https://github.com/smart-dato/gls-authenticator/actions?query=workflow%3A%22Fix+PHP+code+style+issues%22+branch%3Amain)[![Total Downloads](https://camo.githubusercontent.com/1bc3ee8eba39f534a9e3c6c427bc7bfe29550dab0aeb681b569c3f214d708e2a/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f736d6172742d6461746f2f676c732d61757468656e74696361746f722e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/smart-dato/gls-authenticator)

A Laravel package for authenticating with the GLS Group Authentication API v2. This package provides a fluent, cache-enabled interface for obtaining OAuth 2.0 access tokens using the client credentials grant type.

Features
--------

[](#features)

- 🔐 **OAuth 2.0 Authentication** - Client credentials grant type
- 💾 **Automatic Token Caching** - Tokens cached until expiration (4 hours)
- 🔄 **Token Refresh Logic** - Automatic detection and refresh of expired tokens
- 🎯 **Scope Management** - Request tokens with specific OAuth scopes
- 🏢 **Multi-Tenant Support** - Runtime configuration for different credentials
- 🌍 **Environment Switching** - Support for sandbox and production environments
- 🚀 **Fluent API** - Chainable methods for clean, readable code
- ✅ **Fully Tested** - Comprehensive test coverage with Pest PHP

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

[](#requirements)

- PHP 8.4 or higher
- Laravel 11.0 or 12.0

Installation
------------

[](#installation)

You can install the package via composer:

```
composer require smart-dato/gls-authenticator
```

Publish the config file with:

```
php artisan vendor:publish --tag="gls-authenticator-config"
```

Configuration
-------------

[](#configuration)

Add your GLS API credentials to your `.env` file:

```
GLS_CLIENT_ID=your_client_id
GLS_CLIENT_SECRET=your_client_secret
GLS_ENVIRONMENT=sandbox  # or 'production'

# Optional
GLS_SCOPES="parcel.create parcel.read"
GLS_CACHE_STORE=redis
GLS_CACHE_PREFIX=gls_auth
```

The published config file (`config/gls-authenticator.php`) includes:

```
return [
    // Default environment: 'sandbox' or 'production'
    'environment' => env('GLS_ENVIRONMENT', 'sandbox'),

    // OAuth2 client credentials
    'client_id' => env('GLS_CLIENT_ID'),
    'client_secret' => env('GLS_CLIENT_SECRET'),

    // API endpoints
    'endpoints' => [
        'sandbox' => 'https://api-sandbox.gls-group.net/oauth2/v2',
        'production' => 'https://api.gls-group.net/oauth2/v2',
    ],

    // Default scopes (space-separated)
    'scopes' => env('GLS_SCOPES', ''),

    // Cache configuration
    'cache' => [
        'store' => env('GLS_CACHE_STORE'),
        'prefix' => env('GLS_CACHE_PREFIX', 'gls_auth'),
        'expiration_buffer' => env('GLS_CACHE_EXPIRATION_BUFFER', 300), // 5 minutes
    ],

    // HTTP client settings
    'http' => [
        'timeout' => env('GLS_HTTP_TIMEOUT', 30),
        'retry' => [
            'times' => env('GLS_HTTP_RETRY_TIMES', 3),
            'sleep' => env('GLS_HTTP_RETRY_SLEEP', 100), // milliseconds
        ],
    ],

    // Authentication method: 'basic_auth' or 'body'
    'auth_method' => env('GLS_AUTH_METHOD', 'basic_auth'),
];
```

Usage
-----

[](#usage)

### Basic Usage

[](#basic-usage)

Get an access token using default configuration:

```
use SmartDato\GlsAuthenticator\Facades\GlsAuthenticator;

$token = GlsAuthenticator::getToken();

// Use the token
$authHeader = $token->toAuthorizationHeader(); // "Bearer eyJ..."
```

### Token Properties

[](#token-properties)

```
$token = GlsAuthenticator::getToken();

echo $token->token;          // The JWT access token
echo $token->tokenType;      // "Bearer"
echo $token->expiresIn;      // 14400 (4 hours in seconds)
echo $token->expiresAt();    // DateTimeInterface
echo $token->isExpired();    // false
echo $token->secondsUntilExpiration(); // 14399
```

### Multi-Tenant / Runtime Configuration

[](#multi-tenant--runtime-configuration)

Perfect for applications serving multiple clients:

```
// Each tenant has their own credentials
$tenant = Tenant::current();

$token = GlsAuthenticator::withCredentials(
    $tenant->gls_client_id,
    $tenant->gls_client_secret
)->getToken();
```

### Environment Switching

[](#environment-switching)

Switch between sandbox and production:

```
// Use sandbox
$token = GlsAuthenticator::environment('sandbox')->getToken();

// Use production
$token = GlsAuthenticator::environment('production')->getToken();
```

### Scope Management

[](#scope-management)

Request specific OAuth scopes:

```
// Array of scopes
$token = GlsAuthenticator::scopes(['parcel.create', 'parcel.read'])->getToken();

// Space-separated string
$token = GlsAuthenticator::scopes('parcel.create parcel.read')->getToken();
```

### Fluent API Chaining

[](#fluent-api-chaining)

Combine multiple configuration options:

```
$token = GlsAuthenticator::withCredentials($clientId, $clientSecret)
    ->environment('production')
    ->scopes(['parcel.create', 'parcel.read'])
    ->getToken();
```

### Force Fresh Token

[](#force-fresh-token)

Bypass cache and get a fresh token from the API:

```
$token = GlsAuthenticator::fresh()->getToken();
```

### Cache Management

[](#cache-management)

```
// Clear token for current credentials
GlsAuthenticator::clearCache();

// Clear all cached tokens
GlsAuthenticator::clearAllTokens();
```

### Check Configuration

[](#check-configuration)

```
if (GlsAuthenticator::isConfigured()) {
    $token = GlsAuthenticator::getToken();
} else {
    // Prompt user to configure credentials
}
```

Token Caching
-------------

[](#token-caching)

Tokens are automatically cached to minimize API calls:

- **Cache Duration**: Tokens expire in 4 hours (14,400 seconds)
- **Cache TTL**: Cached for 3 hours 55 minutes (expires 5 minutes early for safety)
- **Multi-Tenant Isolation**: Each unique credential set has a separate cache key
- **Scope-Specific**: Different scopes generate different cache keys

### Cache Key Format

[](#cache-key-format)

```
{prefix}:{environment}:{client_id_hash}:{scopes_hash}

```

Example: `gls_auth:sandbox:a3f5c8d2:e9b4f1a6`

Error Handling
--------------

[](#error-handling)

The package throws specific exceptions for different error scenarios:

```
use SmartDato\GlsAuthenticator\Exceptions\MissingCredentialsException;
use SmartDato\GlsAuthenticator\Exceptions\InvalidCredentialsException;
use SmartDato\GlsAuthenticator\Exceptions\TokenRequestException;

try {
    $token = GlsAuthenticator::getToken();
} catch (MissingCredentialsException $e) {
    // No credentials configured
    logger()->error('GLS credentials not configured');
} catch (InvalidCredentialsException $e) {
    // Invalid client_id or client_secret
    logger()->error('Invalid GLS credentials', ['errors' => $e->errors]);
} catch (TokenRequestException $e) {
    // API request failed (network error, server error, etc.)
    logger()->error('GLS API request failed', ['message' => $e->getMessage()]);
}
```

Use Cases
---------

[](#use-cases)

### Making API Calls

[](#making-api-calls)

```
use Illuminate\Support\Facades\Http;

$token = GlsAuthenticator::getToken();

$response = Http::withToken($token->token)
    ->post('https://api.gls-group.net/parcel/v1/shipments', [
        // Your shipment data
    ]);
```

### Middleware for Multi-Tenant Apps

[](#middleware-for-multi-tenant-apps)

```
namespace App\Http\Middleware;

use Closure;
use SmartDato\GlsAuthenticator\Facades\GlsAuthenticator;

class SetGlsCredentials
{
    public function handle($request, Closure $next)
    {
        $tenant = $request->user()->tenant;

        // Store token for later use
        $request->attributes->set('gls_token',
            GlsAuthenticator::withCredentials(
                $tenant->gls_client_id,
                $tenant->gls_client_secret
            )->getToken()
        );

        return $next($request);
    }
}
```

### Service Class Example

[](#service-class-example)

```
namespace App\Services;

use SmartDato\GlsAuthenticator\Facades\GlsAuthenticator;
use Illuminate\Support\Facades\Http;

class GlsParcelService
{
    protected $token;

    public function __construct()
    {
        $this->token = GlsAuthenticator::getToken();
    }

    public function createShipment(array $data)
    {
        return Http::withToken($this->token->token)
            ->post('https://api.gls-group.net/parcel/v1/shipments', $data)
            ->json();
    }

    public function trackParcel(string $parcelNumber)
    {
        return Http::withToken($this->token->token)
            ->get("https://api.gls-group.net/parcel/v1/tracking/{$parcelNumber}")
            ->json();
    }
}
```

Testing
-------

[](#testing)

Run the test suite:

```
composer test
```

Run static analysis:

```
composer analyse
```

Format code with Laravel Pint:

```
composer format
```

Run all quality checks:

```
composer test && composer analyse && composer format
```

### Testing Your Application

[](#testing-your-application)

Use Laravel's HTTP facade to mock GLS API responses:

```
use Illuminate\Support\Facades\Http;
use SmartDato\GlsAuthenticator\Facades\GlsAuthenticator;

test('can authenticate with GLS API', function () {
    Http::fake([
        'api-sandbox.gls-group.net/*' => Http::response([
            'token_type' => 'Bearer',
            'access_token' => 'test_token_123',
            'expires_in' => 14400,
        ]),
    ]);

    $token = GlsAuthenticator::getToken();

    expect($token->token)->toBe('test_token_123');
    expect($token->tokenType)->toBe('Bearer');
});
```

API Reference
-------------

[](#api-reference)

For detailed API specifications, see the [OpenAPI documentation](documentation/authentification-service-v2.yaml).

### Endpoints

[](#endpoints)

- **Sandbox**: `https://api-sandbox.gls-group.net/oauth2/v2`
- **Production**: `https://api.gls-group.net/oauth2/v2`

### Token Details

[](#token-details)

- **Grant Type**: `client_credentials`
- **Token Type**: `Bearer`
- **Validity**: 4 hours (14,400 seconds)
- **Rate Limit**: 100,000 requests per App ID per day

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

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

[](#contributing)

Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

Security Vulnerabilities
------------------------

[](#security-vulnerabilities)

Please review [our security policy](../../security/policy) on how to report security vulnerabilities.

Credits
-------

[](#credits)

- [SmartDato](https://github.com/smart-dato)
- [All Contributors](../../contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

36

—

LowBetter than 82% of packages

Maintenance82

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity45

Maturing project, gaining track record

 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

Unknown

Total

1

Last Release

165d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/c3006db55caec62526937fa2d941da32fc5e69e2ca86a52e87c8046da5958d82?d=identicon)[smart-dato](/maintainers/smart-dato)

---

Top Contributors

[![tschigo](https://avatars.githubusercontent.com/u/344100?v=4)](https://github.com/tschigo "tschigo (3 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (1 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (1 commits)")[![michael-tscholl](https://avatars.githubusercontent.com/u/178569346?v=4)](https://github.com/michael-tscholl "michael-tscholl (1 commits)")

---

Tags

laravelSmartDatogls-authenticator

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/smart-dato-gls-authenticator/health.svg)

```
[![Health](https://phpackages.com/badges/smart-dato-gls-authenticator/health.svg)](https://phpackages.com/packages/smart-dato-gls-authenticator)
```

###  Alternatives

[spatie/laravel-permission

Permission handling for Laravel 12 and up

12.9k89.8M1.0k](/packages/spatie-laravel-permission)[bezhansalleh/filament-shield

Filament support for `spatie/laravel-permission`.

2.8k2.9M88](/packages/bezhansalleh-filament-shield)[jeffgreco13/filament-breezy

A custom package for Filament with login flow, profile and teams support.

1.0k1.7M41](/packages/jeffgreco13-filament-breezy)[spatie/laravel-login-link

Quickly login to your local environment

4381.2M1](/packages/spatie-laravel-login-link)[ryangjchandler/laravel-cloudflare-turnstile

A simple package to help integrate Cloudflare Turnstile.

438896.6k2](/packages/ryangjchandler-laravel-cloudflare-turnstile)[spatie/laravel-passkeys

Use passkeys in your Laravel app

444494.4k16](/packages/spatie-laravel-passkeys)

PHPackages © 2026

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