为您的网站提供 Telegram OAuth 授权

2025-06-10

为您的网站提供 Telegram OAuth 授权

您可以通过 Telegram 以另一种方式进行授权。这种方法有效。但今天我们想进行经典的 OAuth 授权。
在开始之前,您需要创建一个 Telegram 机器人并获取您的机器人令牌。您可以在@BotFatherTelegram 中完成此操作。有关启动机器人的更多信息,请阅读 Telegram 机器人 API 文档:https://core.telegram.org/bots

将用户重定向到 Telegram 的 OAuth URL

要启动 OAuth 流程,您需要将用户重定向到以下 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

您必须将YOUR_BOT_IDYOUR_SCOPEYOUR_PUBLIC_KEYYOUR_NONCE替换为您的机器人的特定信息。nonce是一个唯一的、随机生成的字符串,您需要存储它以供以后验证。

处理 Telegram 的 OAuth 回调

用户授权您的应用程序后,Telegram 会将用户重定向回您的网站,URL 包含哈希值和有效负载。您需要验证哈希值、解析有效负载并存储用户信息。
就这样!我本可以结束这篇文章了。不过,好的,我将用我常用的语言(PHP、Node.js 和 Golang)添加示例。

PHP示例:

<?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 示例:

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示例:

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

很简单,不是吗?
当然,这些代码块并非最佳,但它们有助于理解如何使用它。

鏂囩珷鏉ユ簮锛�https://dev.to/shaggyrec/telegram-oauth-authorization-for-your-site-3f4l
PREV
为什么选择类型而不是接口
NEXT
如何保护 TypeScript 应用程序的安全...??