mirror of
https://github.com/aiogram/aiogram.git
synced 2025-12-11 09:55:21 +00:00
Webhook. Allow requests only from Telegram servers. // Optional
This commit is contained in:
parent
6d9bdce935
commit
f050d08c75
2 changed files with 44 additions and 1 deletions
|
|
@ -2,6 +2,7 @@ import asyncio
|
||||||
import asyncio.tasks
|
import asyncio.tasks
|
||||||
import datetime
|
import datetime
|
||||||
import functools
|
import functools
|
||||||
|
import ipaddress
|
||||||
import typing
|
import typing
|
||||||
from typing import Dict, Optional, Union
|
from typing import Dict, Optional, Union
|
||||||
|
|
||||||
|
|
@ -25,6 +26,21 @@ WEBHOOK = 'webhook'
|
||||||
WEBHOOK_CONNECTION = 'WEBHOOK_CONNECTION'
|
WEBHOOK_CONNECTION = 'WEBHOOK_CONNECTION'
|
||||||
WEBHOOK_REQUEST = 'WEBHOOK_REQUEST'
|
WEBHOOK_REQUEST = 'WEBHOOK_REQUEST'
|
||||||
|
|
||||||
|
TELEGRAM_IP_LOWER = ipaddress.IPv4Address('149.154.167.197')
|
||||||
|
TELEGRAM_IP_UPPER = ipaddress.IPv4Address('149.154.167.233')
|
||||||
|
LOCALHOST_IP = ipaddress.IPv4Address('127.0.0.1')
|
||||||
|
|
||||||
|
|
||||||
|
def _check_ip(ip: str) -> bool:
|
||||||
|
"""
|
||||||
|
Check IP in range
|
||||||
|
|
||||||
|
:param ip:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
address = ipaddress.IPv4Address(ip)
|
||||||
|
return TELEGRAM_IP_LOWER <= address <= TELEGRAM_IP_UPPER or address == LOCALHOST_IP
|
||||||
|
|
||||||
|
|
||||||
class WebhookRequestHandler(web.View):
|
class WebhookRequestHandler(web.View):
|
||||||
"""
|
"""
|
||||||
|
|
@ -78,6 +94,11 @@ class WebhookRequestHandler(web.View):
|
||||||
|
|
||||||
:return: :class:`aiohttp.web.Response`
|
:return: :class:`aiohttp.web.Response`
|
||||||
"""
|
"""
|
||||||
|
if self.request.app.get('_check_ip', False):
|
||||||
|
ip_address, accept = self.check_ip()
|
||||||
|
if not accept:
|
||||||
|
raise web.HTTPUnauthorized()
|
||||||
|
context.set_value('TELEGRAM_IP', ip_address)
|
||||||
|
|
||||||
context.update_state({'CALLER': WEBHOOK,
|
context.update_state({'CALLER': WEBHOOK,
|
||||||
WEBHOOK_CONNECTION: True,
|
WEBHOOK_CONNECTION: True,
|
||||||
|
|
@ -164,6 +185,26 @@ class WebhookRequestHandler(web.View):
|
||||||
if isinstance(result, BaseResponse):
|
if isinstance(result, BaseResponse):
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def check_ip(self):
|
||||||
|
"""
|
||||||
|
Check client IP. Accept requests only from telegram servers.
|
||||||
|
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
# For reverse proxy (nginx)
|
||||||
|
forwarded_for = self.request.headers.get('X-Forwarded-For', None)
|
||||||
|
if forwarded_for:
|
||||||
|
return forwarded_for, _check_ip(forwarded_for)
|
||||||
|
|
||||||
|
# For default method
|
||||||
|
peer_name = self.request.transport.get_extra_info('peername')
|
||||||
|
if peer_name is not None:
|
||||||
|
host, _ = peer_name
|
||||||
|
return host, _check_ip(host)
|
||||||
|
|
||||||
|
# Not allowed and can't get client IP
|
||||||
|
return None, False
|
||||||
|
|
||||||
|
|
||||||
def configure_app(dispatcher, app: web.Application, path=DEFAULT_WEB_PATH):
|
def configure_app(dispatcher, app: web.Application, path=DEFAULT_WEB_PATH):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ def start_pooling(dispatcher, *, loop=None, skip_updates=False, on_startup=None,
|
||||||
|
|
||||||
|
|
||||||
def start_webhook(dispatcher, webhook_path, *, loop=None, skip_updates=None, on_startup=None, on_shutdown=None,
|
def start_webhook(dispatcher, webhook_path, *, loop=None, skip_updates=None, on_startup=None, on_shutdown=None,
|
||||||
**kwargs):
|
check_ip=False, **kwargs):
|
||||||
log.warning('Start bot with webhook.')
|
log.warning('Start bot with webhook.')
|
||||||
if loop is None:
|
if loop is None:
|
||||||
loop = dispatcher.loop
|
loop = dispatcher.loop
|
||||||
|
|
@ -72,8 +72,10 @@ def start_webhook(dispatcher, webhook_path, *, loop=None, skip_updates=None, on_
|
||||||
app['_startup_callback'] = on_startup
|
app['_startup_callback'] = on_startup
|
||||||
app['_shutdown_callback'] = on_shutdown
|
app['_shutdown_callback'] = on_shutdown
|
||||||
app['_skip_updates'] = skip_updates
|
app['_skip_updates'] = skip_updates
|
||||||
|
app['_check_ip'] = check_ip
|
||||||
|
|
||||||
app.on_startup.append(_wh_startup)
|
app.on_startup.append(_wh_startup)
|
||||||
app.on_shutdown.append(_wh_shutdown)
|
app.on_shutdown.append(_wh_shutdown)
|
||||||
|
|
||||||
web.run_app(app, loop=loop, **kwargs)
|
web.run_app(app, loop=loop, **kwargs)
|
||||||
|
return app
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue