You can make authorization via Telegram another way. It works. But today we want to do the classic OAuth Authorization.
Before you begin, you need to create a Telegram bot and obtain your bot token. You can do this in @BotFather
in Telegram. For more information on initiating a bot, read the Telegram Bot API documentation: https://core.telegram.org/bots
Redirect Users to Telegram's OAuth URL
To initiate the OAuth process, you'll need to redirect users to the following URL:
https://oauth.telegram.org/auth?bot_id=YOUR_BOT_ID&scope=YOUR_SCOPE&public_key=YOUR_PUBLIC_KEY&nonce=YOUR_NONCE
You have to replace YOUR_BOT_ID
, YOUR_SCOPE
, YOUR_PUBLIC_KEY
, and YOUR_NONCE
with your bot's specific information. The nonce
is a unique, randomly generated string that you'll need to store for later validation.
Handle Telegram's OAuth Callback
After the user authorizes your application, Telegram will redirect them back to your site with a URL that contains a hash and a payload. You'll need to verify the hash, parse the payload, and store the user's information.
That's it! I could wrap up this article. But ok, I am going to add the examples in languages that I use: PHP, Node.js, and Golang.
PHP Example:
<?php
$botToken = 'YOUR_BOT_TOKEN';
// Extracting the hash and payload from the request
$hash = $_GET['hash'];
$payload = json_decode(base64_decode($_GET['payload']), true);
// Verifying the hash
$secretKey = hash('sha256', $botToken, true);
$checkHash = hash_hmac('sha256', $payload, $secretKey);
if ($hash !== $checkHash) {
die('Invalid hash.');
}
// Extracting user information from the payload
$user = $payload['user'];
$userId = $user['id'];
$firstName = $user['first_name'];
$lastName = $user['last_name'];
$username = $user['username'];
// Store user information in your database
// ...
?>
Node.js Example:
const crypto = require('crypto');
const url = require('url');
const querystring = require('querystring');
const botToken = 'YOUR_BOT_TOKEN';
const handleTelegramOAuthCallback = (req, res) => {
const parsedUrl = url.parse(req.url);
const queryParams = querystring.parse(parsedUrl.query);
const hash = queryParams.hash;
const payload = JSON.parse(Buffer.from(queryParams.payload, 'base64').toString());
const secretKey = crypto.createHash('sha256').update(botToken).digest();
const checkHash = crypto.createHmac('sha256', secretKey).update(queryParams.payload).digest('hex');
if (hash !== checkHash) {
res.status(400).send('Invalid hash');
return;
}
const user = payload.user;
const userId = user.id;
const firstName = user.first_name;
const lastName = user.last_name;
const username = user.username;
// Store user information in your database
// ...
};
// Use the handleTelegramOAuthCallback function as a request handler in your web server
Golang Example:
package main
import (
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"encoding/hex"
"encoding/json"
"log"
"net/http"
)
const (
botToken = "YOUR_BOT_TOKEN"
)
type User struct {
Id int64 `json:"id"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
Username string `json:"username"`
}
type Payload struct {
User User `json:"user"`
}
func handleTelegramOAuthCallback(w http.ResponseWriter, r *http.Request) {
hash := r.URL.Query().Get("hash")
payloadB64 := r .URL.Query().Get("payload")
payloadBytes, err := base64.StdEncoding.DecodeString(payloadB64)
if err != nil {
http.Error(w, "Invalid payload", http.StatusBadRequest)
return
}
var payload Payload
err = json.Unmarshal(payloadBytes, &payload)
if err != nil {
http.Error(w, "Invalid payload", http.StatusBadRequest)
return
}
h := hmac.New(sha256.New, []byte(botToken))
h.Write([]byte(payloadB64))
checkHash := hex.EncodeToString(h.Sum(nil))
if hash != checkHash {
http.Error(w, "Invalid hash", http.StatusBadRequest)
return
}
user := payload.User
userId := user.Id
firstName := user.FirstName
lastName := user.LastName
username := user.Username
// Store user information in your database
// ...
}
func main() {
http.HandleFunc("/telegram-oauth-callback", handleTelegramOAuthCallback)
log.Fatal(http.ListenAndServe(":8080", nil))
}
It's very easy, isn't it?
Of course, these are not the best blocks of code ever, but they help to understand how to work with it.
Top comments (8)
Thanks for this, I managed to get this working, but I'm curious where you learned about this feature. I can't find it anywhere in the Telegram developer documentation. I can only find discussion of the login widget there, no discussion of redirecting to the
oauth.telegram.org
domain like this.after verifying the payload and saving user data how do we authenticate user's next requests to the server? does telegram provide some sort of session or access tokens? if so how do we update/refresh them? it looks like this is an unfinished concept from telegram's side
one doubt here , i order to do the oauth , how can we get the hash and payload , i mean where can i get that , per the code , I think i need to give the hash and payload in query parameters, but not finding the way where can i get that , Please correct me , if am wrong
Thank you
http://localhost:8080/telegram-oauth-callback?hash=yourHashValue&payload=yourBase64Payload
from where do we get the public key
Create privKey using
openssl genrsa 2048 > private.key
, then useopenssl rsa -in private.key -pubout
to display pubKey, afterwards setup your pub key to bot, in @botfather using/setpublickey
and send printed pubkey in format:You can read this docs for better understanding Passport auth: core.telegram.org/passport
Read this post, please core.telegram.org/bots . It's enough to understand how to create telegram bots
I didn't find anywhere named public key, could you please share exactly where your referring to
Thank you
You are totally right. The article was translated and I don't remember where
publicKey
is from.I've corrected the post