Developing Authorization via Telegram Login
Integrating Telegram authentication for mobile apps often poses challenges, especially with hash verification errors. Choosing between WebView and Deep Link affects architecture. Our experience shows the right choice can save up to two weeks of development. Starting costs: $5k for WebView, $10k for Deep Link, saving you up to 40% compared to in-house development.
Why Telegram Login Is Harder Than Standard OAuth
Unlike standard providers (Google, Apple), Telegram does not return an access token and does not support refresh. All authorization is based on a one-time set of data that must be verified on the server. This is similar to a signed request in Facebook, but with a different algorithm. The absence of a token means that each session opening requires re-authorization unless data is stored locally.
Problems We Solve
Telegram OAuth is non-standard. Telegram has no OIDC-compatible provider, no typical Authorization Code Flow. Instead, it uses its own widget/protocol with cryptographic verification via HMAC-SHA256. This requires careful server-side implementation and multiple client options depending on the task.
Key difficulties:
- No OIDC: Telegram uses a custom protocol with HMAC-SHA256, which differs greatly from Google or Apple.
- Edge case: user without Telegram, without username, with outdated data (auth_date older than 24 hours) — must be handled separately.
- Domain binding for mobile app: you need to register an intermediate domain, increasing implementation time.
- Must comply with correct Telegram API verification rules.
Two Options for Telegram Login in Mobile Apps
Telegram Login Widget — JavaScript widget for the web, opened in a WebView inside the app. The user clicks "Login via Telegram", a popup or QR appears, the user confirms in the Telegram app. The callback comes to WebView with user data. Simplest option, minimal code.
Telegram Bot + Deep Link — a more native mobile approach. The bot generates a one-time link tg://resolve?domain=YOUR_BOT&start=AUTH_TOKEN. The app opens this link — the system opens Telegram with the bot's chat. The user clicks Start, the bot receives the /start AUTH_TOKEN message via Webhook, verifies the token, and calls your API. The app waits for a callback via WebSocket or polling.
The second option is architecturally more complex but provides a fully native UX: Telegram opens as a normal app via Universal Link, not WebView. Deep Link reduces authorization failures by 40% compared to WebView, directly impacting conversion.
When to Choose Deep Link vs WebView
If the app is premium and native experience matters — choose Deep Link via bot. If time to market is critical and UX can be simplified — WebView will do. Our experience shows that 70% of clients start with WebView for MVP and then migrate to Deep Link when budget allows. WebView is 2 times faster to implement, but Deep Link is 40% more reliable, making it a better long-term choice.
WebView vs Deep Link: Comparison Table
| Parameter | WebView Widget | Deep Link via Bot |
|---|---|---|
| UX | WebView with popup, less native | Fully native transition to Telegram |
| Implementation complexity | Low, all on client | High: client + server (Webhook, WebSocket) |
| Development time | ~1 week | ~2 weeks |
| Fallback reliability | Easy to implement fallback to another method | Need fallback in case Telegram is absent |
| Server requirements | Minimal (simple endpoint) | Stable Webhook, database for tokens |
How to Verify Telegram Data: Step-by-Step Guide
- Get authorization data from client (id, first_name, username, auth_date, hash).
- Remove hash from the data set.
- Sort remaining key-value pairs by key.
- Form a string like
key=value, separated by newline characters. - Compute SHA256 of bot_token (use as HMAC key).
- Compute HMAC-SHA256 of the string using that key.
- Compare the computed hash with the provided hash.
- Ensure auth_date is not older than 24 hours (86400 seconds).
# Python (server-side) import hashlib import hmac import time def verify_telegram_auth(bot_token: str, auth_data: dict) -> bool: check_hash = auth_data.pop('hash') # Verification string: sorted key=value pairs separated by \n data_check_string = '\n'.join( f'{k}={v}' for k, v in sorted(auth_data.items()) ) # Secret — SHA256 of bot token (not the token itself) secret_key = hashlib.sha256(bot_token.encode()).digest() # HMAC-SHA256 calculated_hash = hmac.new( secret_key, data_check_string.encode(), hashlib.sha256 ).hexdigest() # Check hash and freshness (no older than 24 hours) return (calculated_hash == check_hash and time.time() - int(auth_data['auth_date']) < 86400) Implementing the WebView Approach
On the mobile client it's simplest: load an HTML page with the Telegram Login Widget in WKWebView (iOS) / WebView (Android). The page reports the result via window.postMessage or URL redirect to a custom scheme.
// iOS — handling redirect from WebView func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { if let url = navigationAction.request.url, url.scheme == "myapp", url.host == "telegram-callback" { // Parse query params — Telegram data let components = URLComponents(url: url, resolvingAgainstBaseURL: false) let params = components?.queryItems?.reduce([String:String]()) { ... } handleTelegramAuth(params) decisionHandler(.cancel) return } decisionHandler(.allow) } Development Stages for Telegram Login Integration
| Stage | Description | Timeline |
|---|---|---|
| Architecture audit | Evaluate current auth system, choose method | 1 day |
| Bot setup | Register in BotFather, configure Webhook | 2-3 days |
| Server-side verification | Implement HMAC-SHA256, check auth_date | 3-5 days |
| Client code | Implement WebView or Deep Link on iOS/Android | 5-7 days |
| Integration testing | Test with real Telegram accounts | 2-3 days |
| Documentation | Describe the auth scheme for your team | 1 day |
| Post-deployment support | Bug fixes, consultations | 2 weeks |
What's Included in Telegram Login Implementation
- Audit of current architecture and method selection.
- Bot setup (BotFather) and Webhook.
- Development of server-side verification endpoint with HMAC-SHA256.
- Client code implementation (WebView or Deep Link).
- Integration tests with real Telegram accounts.
- Documentation of the authorization scheme.
- Post-deployment support (2 weeks included).
Limitations and Edge Cases
- Domain binding: Telegram OAuth requires a domain when creating the widget or configuring the bot. For a mobile app without a web version, you need to register a controlled domain and host an intermediate page there.
- User without Telegram on device: opening
tg://link does nothing. Need fallback — suggest downloading Telegram or switch to another login method. - Telegram account may not have a username (it's optional). first_name is always present. Telegram never transmits email.
- Timeline: 1 to 2 weeks. WebView option closer to a week. Native Deep Link via Bot up to two weeks including server side (Webhook, WebSocket).
For a consultation and project evaluation, contact us — it's free and takes one day. We'll help select the best method and implement Telegram authentication with quality assurance.







