如何在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
相关产品推荐
相关产品推荐

