Instantly share code, notes, and snippets.

Embed
What would you like to do?
<?php
define('BOT_TOKEN', 'XXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXX'); // place bot token of your bot here
function checkTelegramAuthorization($auth_data) {
$check_hash = $auth_data['hash'];
unset($auth_data['hash']);
$data_check_arr = [];
foreach ($auth_data as $key => $value) {
$data_check_arr[] = $key . '=' . $value;
}
sort($data_check_arr);
$data_check_string = implode("\n", $data_check_arr);
$secret_key = hash('sha256', BOT_TOKEN, true);
$hash = hash_hmac('sha256', $data_check_string, $secret_key);
if (strcmp($hash, $check_hash) !== 0) {
throw new Exception('Data is NOT from Telegram');
}
if ((time() - $auth_data['auth_date']) > 86400) {
throw new Exception('Data is outdated');
}
return $auth_data;
}
function saveTelegramUserData($auth_data) {
$auth_data_json = json_encode($auth_data);
setcookie('tg_user', $auth_data_json);
}
try {
$auth_data = checkTelegramAuthorization($_GET);
saveTelegramUserData($auth_data);
} catch (Exception $e) {
die ($e->getMessage());
}
header('Location: login_example.php');
?>
<?php
define('BOT_USERNAME', 'XXXXXXXXXX'); // place username of your bot here
function getTelegramUserData() {
if (isset($_COOKIE['tg_user'])) {
$auth_data_json = urldecode($_COOKIE['tg_user']);
$auth_data = json_decode($auth_data_json, true);
return $auth_data;
}
return false;
}
if ($_GET['logout']) {
setcookie('tg_user', '');
header('Location: login_example.php');
}
$tg_user = getTelegramUserData();
if ($tg_user !== false) {
$first_name = htmlspecialchars($tg_user['first_name']);
$last_name = htmlspecialchars($tg_user['last_name']);
if (isset($tg_user['username'])) {
$username = htmlspecialchars($tg_user['username']);
$html = "<h1>Hello, <a href=\"https://t.me/{$username}\">{$first_name} {$last_name}</a>!</h1>";
} else {
$html = "<h1>Hello, {$first_name} {$last_name}!</h1>";
}
if (isset($tg_user['photo_url'])) {
$photo_url = htmlspecialchars($tg_user['photo_url']);
$html .= "<img src=\"{$photo_url}\">";
}
$html .= "<p><a href=\"?logout=1\">Log out</a></p>";
} else {
$bot_username = BOT_USERNAME;
$html = <<<HTML
<h1>Hello, anonymous!</h1>
<script async src="https://telegram.org/js/telegram-widget.js?2" data-telegram-login="{$bot_username}" data-size="large" data-auth-url="check_authorization.php"></script>
HTML;
}
echo <<<HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Login Widget Example</title>
</head>
<body><center>{$html}</center></body>
</html>
HTML;
?>
@ximik777

This comment has been minimized.

ximik777 commented Feb 7, 2018

Does not work. =(

@ximik777

This comment has been minimized.

ximik777 commented Feb 7, 2018

Already working! =)

@ingria

This comment has been minimized.

ingria commented Feb 7, 2018

Doesn't work in Firefox

Error: NOT_ALLOWED

@Alisummer

This comment has been minimized.

Alisummer commented Feb 7, 2018

Good!

@jumong

This comment has been minimized.

jumong commented Feb 7, 2018

Bot domain empty ? Why ?

@kapter

This comment has been minimized.

kapter commented Feb 7, 2018

"Bot domain empty"??

@jumong

This comment has been minimized.

jumong commented Feb 7, 2018

Bot domain empty error

@ruslanmedia

This comment has been minimized.

ruslanmedia commented Feb 7, 2018

@jumong, you should set domain by @Botfather

@ivanfmartinez

This comment has been minimized.

ivanfmartinez commented Feb 7, 2018

Does not work on firefox, it returns Error: NOT_ALLOWED (in response payload), and does not redirect to data-auth-url.
No visible information for user in browser.

@kapter

This comment has been minimized.

kapter commented Feb 7, 2018

@ruslanmedia, i send /setdomain command, choose my bot but have error "Bot domain empty". What's wrong?

@jumong

This comment has been minimized.

jumong commented Feb 7, 2018

@ruslanmedia Рахмат котта!

@kricha

This comment has been minimized.

kricha commented Feb 7, 2018

i also have error Bot domain empty

@jumong

This comment has been minimized.

jumong commented Feb 7, 2018

Who know? How to set own button name ?

@diseks

This comment has been minimized.

diseks commented Feb 7, 2018

Hi. Does anyone known how to use custom button (without text, only custom image)?

@lensws

This comment has been minimized.

lensws commented Feb 7, 2018

Waiting wordpress login

@juananpe

This comment has been minimized.

juananpe commented Feb 7, 2018

Same "Bot domain empty" problem here.

@ximik777

This comment has been minimized.

ximik777 commented Feb 7, 2018

++

Doesn't work in Firefox
Error: NOT_ALLOWED

@9kopb

This comment has been minimized.

9kopb commented Feb 7, 2018

you need to link your domain to the bot first

@juananpe

This comment has been minimized.

juananpe commented Feb 7, 2018

Ah! Thanks @9kopb... I was going to answer that I've already done that but then I tried again and this time it worked! For the record:

Start a conversation with the BotFather. Type "/mybots". Select your bot. Select "Bot settings". Select "Domain". Then type your domain name. You'll get a feedback message from BotFather like this: "Success! Domain updated. /help"

@akkez

This comment has been minimized.

akkez commented Feb 7, 2018

Дуров верни дуровдурова

@lifeact

This comment has been minimized.

lifeact commented Feb 7, 2018

How about asp mvc?

@Serdg

This comment has been minimized.

Serdg commented Feb 7, 2018

How about iOS and Android login with Telegram?

@t4hor3

This comment has been minimized.

t4hor3 commented Feb 7, 2018

It does not work, error 500. What version of PHP is necessary?

@oxmix

This comment has been minimized.

oxmix commented Feb 7, 2018

FF 58.0.1
bug! return string get -> "...username=Oxmix&photo_url=**https:/**t.me/i/userpic/320/Oxmix.jpg&auth_date=151..."
below a temporary fix
$data_check_arr[] = $key . '=' . str_replace('https:/t', 'https://t', $value);
without this fix, hash_hmac checking fail

@amirrammari

This comment has been minimized.

amirrammari commented Feb 7, 2018

Working good :)

@madl-ash

This comment has been minimized.

madl-ash commented Feb 7, 2018

im trying to port this to python but hash_hmac fails.
docs says Data-check-string is a concatenation of all received fields, sorted in alphabetical order
now all fields are id, first_name, last_name, username, photo_url, auth_date and hash;
which fields should i include and in what order exactly?

@roxblnfk

This comment has been minimized.

roxblnfk commented Feb 8, 2018

Does anyone know how to force a telegram to redirect a user to my page (without using a widget)?
Need a workflow similar to OAuth2

I just send the user to https://oauth.telegram.org/bot_id=****

After confirming the user redirects to https://oauth.telegram.org/close

I tried to find the GET param as redirect_uri - unsuccessfully.

Also it would be good to receive POST data

@m0cmc

This comment has been minimized.

m0cmc commented Feb 8, 2018

Great feature!
But returns "Bot domain invalid" for a ".LIVE" domain (which is set on the bot using BotFather). What's wrong ?

@andre-web

This comment has been minimized.

andre-web commented Feb 8, 2018

How I can send message to user if allow access to send messages?

@ImTheDeveloper

This comment has been minimized.

ImTheDeveloper commented Feb 8, 2018

Any easy way to set a local development environment domain?

http://localhost:1337 for example would not register as a domain

@6o6p1k

This comment has been minimized.

6o6p1k commented Feb 9, 2018

How set localhost as domain??
BotFather return: "The message should contain one domain name."

@6o6p1k

This comment has been minimized.

6o6p1k commented Feb 9, 2018

PS Use http://127.0.0.1:youPort/ if you need localhost

@parsibox

This comment has been minimized.

parsibox commented Feb 10, 2018

you most limit GET key to only your key
your key is 'username' , 'auth_date' ,'first_name', 'last_name' ,'photo_url' ,'id'
please fix this
it is correct

function checkTelegramAuthorization($auth_data) {
$allow_key= array('username' , 'auth_date' ,'first_name', 'last_name' ,'photo_url' ,'id');
  $check_hash = $auth_data['hash'];
  unset($auth_data['hash']);
  $data_check_arr = [];
  foreach ($auth_data as $key => $value) {
      if( in_array( $key , $allow_key)){
            $data_check_arr[] = $key . '=' . $value;
      }
  }
  sort($data_check_arr);
  $data_check_string = implode("\n", $data_check_arr);
  $secret_key = hash('sha256', BOT_TOKEN, true);
  $hash = hash_hmac('sha256', $data_check_string, $secret_key);
  if (strcmp($hash, $check_hash) !== 0) {
    throw new Exception('Data is NOT from Telegram');
  }
  if ((time() - $auth_data['auth_date']) > 86400) {
    throw new Exception('Data is outdated');
  }
  return $auth_data;
}
@Aliham

This comment has been minimized.

Aliham commented Feb 10, 2018

پاسخ نداد

@emadweb

This comment has been minimized.

emadweb commented Feb 11, 2018

$check_hash an $hash will not be the same

@xen

This comment has been minimized.

xen commented Feb 12, 2018

In case somebody needs python version https://gist.github.com/xen/e4bea72487d34caa28c762776cf655a3

@tcapb

This comment has been minimized.

tcapb commented Feb 13, 2018

Unusable to me. It allows to add only one domain per bot. I couldn't even use it with multiple subdomains. If i set domain.com - i can use authorization from domain.com page, but cannot - from sub.domain.com page.

@recoilme

This comment has been minimized.

recoilme commented Feb 14, 2018

GoLang version of checkTelegramAuthorization: https://gist.github.com/recoilme/a1b9059b5d5f12c18a63bae58b3bc659

@recoilme

This comment has been minimized.

recoilme commented Feb 14, 2018

@tcapb similar problem. I will redirect login on main domain, set cookie for main domain and subdomains and redirect back. Not finished right now - http://recoilmeblog.tggram.com/

@Pitasi

This comment has been minimized.

@vitalyster

This comment has been minimized.

vitalyster commented Feb 15, 2018

Login widget does not work in Safari (iOS) - it opens new page with "Origin required" text

@Stajor

This comment has been minimized.

@bun4uk

This comment has been minimized.

bun4uk commented Feb 15, 2018

How is it possible to test on localhost?
I crated a bot and conected a domain to it.
image
image

@vitalyster

This comment has been minimized.

vitalyster commented Feb 15, 2018

new page with "Origin required" text

Same issue on Android System Webview

@sajjad-021

This comment has been minimized.

sajjad-021 commented Feb 18, 2018

This is corrected and running without problem ;-)

@seyedahmadqolamy

This comment has been minimized.

seyedahmadqolamy commented Feb 19, 2018

hi, how to use these files and code in wordpress?
do i insert codes in which ones: theme file? or text widget in sidbar?
i want to write code and dont want to use plugin. thanx.

@jhuesser

This comment has been minimized.

jhuesser commented Feb 21, 2018

new page with "Origin required" text

Have this problem to, mostly after I deleted cookies of telegram.org & my page. Still works fine in Chrome on same the same iOS device

@hprobotic

This comment has been minimized.

hprobotic commented Feb 22, 2018

Here is sample implement for React: https://github.com/hprobotic/react-telegram-login

@vchaptsev

This comment has been minimized.

vchaptsev commented Feb 24, 2018

Here is Vue component, if someone need it :)

@yi

This comment has been minimized.

yi commented Feb 27, 2018

web login works on Android Chrome browser. Not working Android webview, nor iOS Safari. Any idea to make it work? please

@MJ-Vakili

This comment has been minimized.

MJ-Vakili commented Mar 2, 2018

How I can send message to user if allow access to send messages?
How start a conversation by bot?
I tried a lot but failed.
Tanks.

@m3night

This comment has been minimized.

m3night commented Mar 4, 2018

Works on firefox desktop , but don't work on firefox on an android device.

@balashovka

This comment has been minimized.

balashovka commented Mar 7, 2018

hi. logIN is work. anybody know how to logOUT authorized user?

@mohammadhoseinpari

This comment has been minimized.

mohammadhoseinpari commented Mar 19, 2018

Tanks

@nadernmds

This comment has been minimized.

nadernmds commented Mar 22, 2018

any one can translate this to c#????
just auth part is enough

@akicreative

This comment has been minimized.

akicreative commented Apr 2, 2018

I have been trying to integrate this with my web sites. But sometimes.... not all the time I get this issue: Invalid 'X-Frame-Options' header encountered when loading

So the widget loads and then when you click it won't do anything. It is a pain, and not very reliable. This is in Safari.

@t1maccapp

This comment has been minimized.

t1maccapp commented Apr 10, 2018

You can use 127.0.0.1 with port 80 to test it locally.

@matinbeigi97

This comment has been minimized.

matinbeigi97 commented Apr 10, 2018

working file in login_example.php

@matinbeigi97

This comment has been minimized.

matinbeigi97 commented Apr 10, 2018

but not work check_authorization.php
recive message Data is NOT from Telegram

@AlexR1712

This comment has been minimized.

AlexR1712 commented May 7, 2018

is working fine

@edu2004eu

This comment has been minimized.

edu2004eu commented May 9, 2018

For anyone who set their domain and still receiving a domain-related errors, note that you can't use ports inside domain names. BotFather will accept it, but the widget will not load. You need to use port 80.

@90K2

This comment has been minimized.

@jehan96

This comment has been minimized.

jehan96 commented May 27, 2018

anyone know how to allow only specific user can login using the widget?

@Vitalicus

This comment has been minimized.

Vitalicus commented May 27, 2018

How to get also phone number on login?

@prutya

This comment has been minimized.

prutya commented Jun 5, 2018

@Stajor Thank you a lot!

@ha93715

This comment has been minimized.

ha93715 commented Jun 7, 2018

Thank you a lot

@DKorablin

This comment has been minimized.

DKorablin commented Jun 25, 2018

C#

private static Boolean ValidateHash(String secretKey, String telegramUrl)
{
	String urlHash = null;
	IEnumerable<String> datas = telegramUrl
		.Split(new Char[] { '&', '?', }, StringSplitOptions.RemoveEmptyEntries)
		.Where(p => { if(p.StartsWith("hash=")) { urlHash = p.Substring("hash=".Length); return false; } else return true; })
		.OrderBy(p => p);

	String dataCheckString = String.Join("\n", datas);

	using(SHA256 sha256 = SHA256Managed.Create("sha256"))
	{
		Byte[] bSecretKey = sha256.ComputeHash(Encoding.UTF8.GetBytes(secretKey));
		using(HMACSHA256 hmacsha256 = new HMACSHA256(bSecretKey))
		{
			Byte[] hash = hmacsha256.ComputeHash(Encoding.UTF8.GetBytes(dataCheckString));
			String strHash = String.Join(String.Empty, hash.Select(p => p.ToString("x2")));
			return strHash == urlHash;
		}
	}
}
@sgyyz

This comment has been minimized.

sgyyz commented Jul 5, 2018

login widget is not working in Telegram in App browser on iOS 10 and below. Did there anyone meet this issue?

@monoplasty

This comment has been minimized.

monoplasty commented Jul 6, 2018

There are no 'photo_url' and 'username' fields in the parameters of the callback function. Did there anyone meet this issue?

@wukexiu

This comment has been minimized.

wukexiu commented Aug 21, 2018

Object-C check_authorization

/**
 Telegram @return to check hash
 
 @param plaintext: already sorted and not contain 'hash' parameters
                   e.g @"auth_date=<auth_date>\nfirst_name=<first_name>\nid=<id>\n...".
 @param token: BOT_TOKEN e.g @"XXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXX"
 @return Hash value calculated by myself
 */
- (NSString *)_hmac256:(NSString *)plaintext withToken:(NSString *)token
{
    NSData *tokenData =  [token dataUsingEncoding:NSUTF8StringEncoding];
    uint8_t digest[CC_SHA256_DIGEST_LENGTH] = {0};
    CC_SHA256(tokenData.bytes, (CC_LONG)tokenData.length, digest);
    NSData *cKey = [NSData dataWithBytes:digest length:CC_SHA256_DIGEST_LENGTH];
    
    NSData *cData = [plaintext dataUsingEncoding:NSUTF8StringEncoding];
    
    unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH];
    CCHmac(kCCHmacAlgSHA256, cKey.bytes, cKey.length, cData.bytes, cData.length, cHMAC);
    NSData *HMACData = [NSData dataWithBytes:cHMAC length:sizeof(cHMAC)];
    const unsigned char *buffer = (const unsigned char *)[HMACData bytes];
    NSMutableString *HMAC = [NSMutableString stringWithCapacity:HMACData.length * 2];
    for (int i = 0; i < HMACData.length; ++i){
        [HMAC appendFormat:@"%02x", buffer[i]];
    }
    return HMAC;
}
@4ibo

This comment has been minimized.

4ibo commented Sep 2, 2018

Typescript

function checkTelegramAuth(auth: TelegramAuthenticateDto): boolean {
    const now = Date.now() / 1000;
    const timeDiff = now - auth.auth_date;

    const checkString: string = Object.keys(auth)
      .filter(key => key !== 'hash')
      .map(key => `${key}=${auth[key]}`)
      .sort()
      .join('\n');

    const secret = crypto
      .createHash('sha256')
      .update(constants.telegram.bot.token)
      .digest();

    const hash = crypto
      .createHmac('sha256', secret)
      .update(checkString)
      .digest('hex');

    return auth.hash === hash && timeDiff < constants.telegram.authExpiresIn;
  }
@manzoorwanijk

This comment has been minimized.

manzoorwanijk commented Sep 24, 2018

WordPress plugin based on that
https://wordpress.org/plugins/wptelegram-login/

@TheNeikos

This comment has been minimized.

TheNeikos commented Oct 22, 2018

A note: You need to have third party cookies enabled for this to work

@sintetico82

This comment has been minimized.

sintetico82 commented Oct 30, 2018

Hi,
After an user is logged in with Telegram Widget, it's possibile to use the bot to notify user somethings?

@1019238091

This comment has been minimized.

1019238091 commented Nov 7, 2018

++

Doesn't work in Firefox
Error: NOT_ALLOWED

The sample to you. Can someone tell me how to do authroize and get user information in the Android.

@zengxiang1

This comment has been minimized.

zengxiang1 commented Nov 28, 2018

There are no 'photo_url' and 'username' fields in the parameters of the callback function. Did there anyone meet this issue?

me too

@paulojp-dev

This comment has been minimized.

paulojp-dev commented Nov 28, 2018

It's working!

@AlexanderSysoev

This comment has been minimized.

AlexanderSysoev commented Dec 2, 2018

Should photo_url be urlencoded to calculate hash?

@jtfell

This comment has been minimized.

jtfell commented Dec 5, 2018

@364578357

This comment has been minimized.

364578357 commented Dec 10, 2018

A2YQF8MK

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment