e4se/laravel-telegram-oidc

OpenID Telegram Connect OAuth2 Provider for Laravel Socialite

Maintainers

Package info

github.com/e4se/laravel-telegram-oidc

pkg:composer/e4se/laravel-telegram-oidc

Statistics

Installs: 23

Dependents: 0

Suggesters: 0

Stars: 2

Open Issues: 0

v1.1.0 2026-04-15 14:30 UTC

This package is auto-updated.

Last update: 2026-04-15 14:30:55 UTC


README

Laravel Support: v9, v10, v11, v12 PHP Support: 8.1, 8.2, 8.3

Installation & Basic Usage

composer require e4se/laravel-telegram-oidc

Please see the Base Installation Guide, then follow the provider specific instructions below.

This provider implements Telegram's current OpenID Connect login flow documented at core.telegram.org/bots/telegram-login.

Telegram setup

Before configuring Laravel, make sure your bot is prepared in Telegram:

  • Open @BotFather and navigate to Bot Settings > Web Login
  • Register every allowed website origin and callback URL you plan to use
  • Copy the Client ID and Client Secret shown by BotFather

Telegram only accepts login requests and redirects for pre-registered URLs.

Add configuration to config/services.php

'telegram-oidc' => [
    'client_id' => env('TELEGRAM_OIDC_CLIENT_ID'),
    'client_secret' => env('TELEGRAM_OIDC_CLIENT_SECRET'),
    'redirect' => env('TELEGRAM_OIDC_REDIRECT_URI'),
],

Add provider event listener

Configure the package's listener to listen for SocialiteWasCalled events.

Laravel 11+

In Laravel 11, the default EventServiceProvider provider was removed. Instead, add the listener using the listen method on the Event facade, in your AppServiceProvider boot method.

Event::listen(function (\SocialiteProviders\Manager\SocialiteWasCalled $event) {
    $event->extendSocialite('telegram-oidc', \SocialiteProviders\TelegramOIDC\Provider::class);
});

Laravel 10 or below

Add the event to your listen[] array in app/Providers/EventServiceProvider. See the Base Installation Guide for detailed instructions.

protected $listen = [
    \SocialiteProviders\Manager\SocialiteWasCalled::class => [
        // ... other providers
        \SocialiteProviders\TelegramOIDC\TelegramOIDCExtendSocialite::class.'@handle',
    ],
];

Usage

You should now be able to use the provider like you would regularly use Socialite (assuming you have the facade installed):

return Socialite::driver('telegram-oidc')->redirect();

By default the provider uses PKCE (S256) and validates the returned id_token against Telegram's JWKS, including iss, aud, and exp, as required by the official documentation.

Returned User fields

  • id
  • name
  • nickname
  • avatar

More fields are available under the user subkey:

$user = Socialite::driver('telegram-oidc')->user();

$phone_number = $user->user['phone_number'];

Telegram returns user claims directly in the id_token. Telegram does not currently expose a separate userinfo endpoint, so this provider reads the authenticated user from the validated ID token instead.

Customizing the scopes

You may extend the default scopes (openid profile) by adding a scopes option to your OIDC service configuration and separate multiple scopes with a space. Telegram currently documents phone and telegram:bot_access as additional available scopes:

'telegram-oidc' => [
    'client_id' => env('TELEGRAM_OIDC_CLIENT_ID'),
    'client_secret' => env('TELEGRAM_OIDC_CLIENT_SECRET'),
    'redirect' => env('TELEGRAM_OIDC_REDIRECT_URI'),
    'scopes' => 'phone',
    // or
    'scopes' => env('TELEGRAM_OIDC_SCOPES'),
],

PKCE

PKCE is enabled by default to match Telegram's recommended authorization code flow. If you need to disable it for compatibility testing, you can do so explicitly:

'telegram-oidc' => [
    'client_id' => env('TELEGRAM_OIDC_CLIENT_ID'),
    'client_secret' => env('TELEGRAM_OIDC_CLIENT_SECRET'),
    'redirect' => env('TELEGRAM_OIDC_REDIRECT_URI'),
    'use_pkce' => false,
],

Proxy and HTTP timeouts

You may route Telegram OIDC requests through a proxy directly from the provider config:

'telegram-oidc' => [
    'client_id' => env('TELEGRAM_OIDC_CLIENT_ID'),
    'client_secret' => env('TELEGRAM_OIDC_CLIENT_SECRET'),
    'redirect' => env('TELEGRAM_OIDC_REDIRECT_URI'),
    'proxy' => env('TELEGRAM_OIDC_PROXY', env('TELEGRAM_PROXY')),
    'connect_timeout' => env('TELEGRAM_OIDC_CONNECT_TIMEOUT'),
    'timeout' => env('TELEGRAM_OIDC_TIMEOUT'),
],

For advanced transport customization you can still pass raw Guzzle options via guzzle. Explicit guzzle options take precedence over the top-level proxy, connect_timeout, and timeout keys:

'telegram-oidc' => [
    'client_id' => env('TELEGRAM_OIDC_CLIENT_ID'),
    'client_secret' => env('TELEGRAM_OIDC_CLIENT_SECRET'),
    'redirect' => env('TELEGRAM_OIDC_REDIRECT_URI'),
    'proxy' => env('TELEGRAM_OIDC_PROXY'),
    'guzzle' => array_filter([
        'proxy' => env('TELEGRAM_OIDC_GUZZLE_PROXY'),
        'verify' => env('TELEGRAM_OIDC_VERIFY_TLS', true),
    ], static fn ($value) => $value !== null && $value !== ''),
],

Based on the work of Kovah