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
// Your bot token and public key
$botToken = 'YOUR_BOT_TOKEN';
$publicKey = 'YOUR_PUBLIC_KEY';
// 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 . $publicKey, 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 publicKey = 'YOUR_PUBLIC_KEY';
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 + publicKey).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"
publicKey = "YOUR_PUBLIC_KEY"
)
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+publicKey))
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 (0)