Telegram OAuth Authorization for Your Site

shaggyrec

Alex Awesome

Posted on March 24, 2023

Telegram OAuth Authorization for Your Site

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
Enter fullscreen mode Exit fullscreen mode

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
// ...

?>
Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

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))
}

Enter fullscreen mode Exit fullscreen mode

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.

💖 💪 🙅 🚩
shaggyrec
Alex Awesome

Posted on March 24, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related