You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django REST Framework中实现Telegram Bot身份验证

解决方案:为Telegram Bot请求实现API身份验证

基于你已有的Django+allauth+SimpleJWT配置,这里提供两种实用方案,让Telegram Bot能安全调用你的REST API:


方案一:自定义Telegram专属认证后端

直接通过Telegram用户ID关联Django用户,无需额外令牌管理,适合实时性请求场景。

1. 创建自定义认证后端
# authentication/backends.py
from django.contrib.auth import get_user_model
from allauth.socialaccount.models import SocialAccount

User = get_user_model()

class TelegramBotAuthBackend:
    def authenticate(self, request, telegram_user_id=None):
        try:
            # 通过Telegram的user_id找到关联的Django用户
            social_account = SocialAccount.objects.get(provider='telegram', uid=telegram_user_id)
            return social_account.user
        except SocialAccount.DoesNotExist:
            return None

    def get_user(self, user_id):
        try:
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
            return None
2. 实现DRF认证类
# authentication/authentication.py
from rest_framework import authentication
from rest_framework.exceptions import AuthenticationFailed
from .backends import TelegramBotAuthBackend

class TelegramBotAuthentication(authentication.BaseAuthentication):
    def authenticate(self, request):
        # 从请求头获取验证信息
        telegram_user_id = request.headers.get('X-Telegram-User-ID')
        bot_token = request.headers.get('X-Telegram-Bot-Token')
        
        # 验证Bot合法性
        if bot_token != 'YOUR_ACTUAL_TELEGRAM_BOT_TOKEN':
            raise AuthenticationFailed("无效的Bot令牌")
        
        if not telegram_user_id:
            raise AuthenticationFailed("缺少Telegram用户ID")
        
        # 匹配Django用户
        backend = TelegramBotAuthBackend()
        user = backend.authenticate(request, telegram_user_id=telegram_user_id)
        
        if not user:
            raise AuthenticationFailed("未找到关联用户")
        
        return (user, None)
3. 更新配置

在settings.py中添加新的认证后端:

AUTHENTICATION_BACKENDS = (
    'registration.authenticate_backend.EmailOrUsernameModelBackend',
    'allauth.account.auth_backends.AuthenticationBackend',
    'authentication.backends.TelegramBotAuthBackend',  # 新增
)
4. 为API视图指定认证类
# views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from authentication.authentication import TelegramBotAuthentication

class UserProfileAPI(APIView):
    authentication_classes = [TelegramBotAuthentication]
    permission_classes = [IsAuthenticated]

    def get(self, request):
        return Response({
            'username': request.user.username,
            'email': request.user.email,
            'telegram_id': request.user.socialaccount_set.get(provider='telegram').uid
        })
5. Bot端调用示例
# Telegram Bot代码片段
import requests

API_ENDPOINT = "https://your-domain.com/api/user-profile/"
BOT_TOKEN = "YOUR_ACTUAL_TELEGRAM_BOT_TOKEN"

def fetch_user_profile(telegram_user_id):
    headers = {
        'X-Telegram-User-ID': str(telegram_user_id),
        'X-Telegram-Bot-Token': BOT_TOKEN
    }
    response = requests.get(API_ENDPOINT, headers=headers)
    return response.json()

方案二:为Telegram用户生成JWT令牌

利用现有SimpleJWT系统,生成令牌供Bot存储使用,适合高频API调用场景,减少数据库查询。

1. 创建令牌生成API
# views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.exceptions import AuthenticationFailed
from rest_framework_simplejwt.tokens import RefreshToken
from allauth.socialaccount.models import SocialAccount

class TelegramJWTTokenAPI(APIView):
    def post(self, request):
        telegram_user_id = request.data.get('telegram_user_id')
        bot_token = request.data.get('bot_token')
        
        if bot_token != 'YOUR_ACTUAL_TELEGRAM_BOT_TOKEN':
            raise AuthenticationFailed("无效的Bot令牌")
        
        try:
            social_account = SocialAccount.objects.get(provider='telegram', uid=telegram_user_id)
            user = social_account.user
            refresh = RefreshToken.for_user(user)
            return Response({
                'refresh': str(refresh),
                'access': str(refresh.access_token),
            })
        except SocialAccount.DoesNotExist:
            raise AuthenticationFailed("未找到关联用户")
2. Bot端使用令牌调用API
# 获取令牌后,后续请求携带Authorization头
headers = {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
}
response = requests.get("https://your-domain.com/api/user-profile/", headers=headers)

方案对比

方案优点缺点
自定义认证后端无需存储令牌,安全性高,实时验证每次请求需查询数据库,性能略低
JWT令牌减少数据库查询,性能更好需要Bot管理令牌有效期,处理刷新逻辑

安全注意事项

  • Bot令牌务必存储在安全的环境变量中,禁止硬编码在代码里
  • 所有API请求必须使用HTTPS,防止头信息被窃取
  • 若Bot通过Webhook接收消息,可额外验证Telegram的Webhook签名,确保请求来自官方服务器

内容的提问来源于stack exchange,提问作者Pet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 19:27:21