⚠️ Временно недоступно
Документация API B4ID
Добро пожаловать в документацию B4ID OAuth 2.0 API. Эта документация поможет вам интегрировать B4ID в ваше приложение.
Содержание
1. Быстрый старт 2. Создание приложения 3. OAuth 2.0 Flow 4. API Endpoints 5. Примеры интеграции 6. Часто задаваемые вопросы
---
Быстрый старт
Чтобы интегрировать B4ID в ваше приложение, вам нужно:
1. Создать OAuth приложение (только для разработчика с telegram_id = 2071861510) 2. Получить Client ID и Client Secret 3. Настроить Redirect URI 4. Реализовать OAuth 2.0 Authorization Code Flow
---
Создание приложения
Шаг 1: Авторизация разработчика
Только пользователь с определенным telegram_id может создавать приложения. Авторизуйтесь через Telegram или email.
Шаг 2: Создание приложения
1. Перейдите в раздел "Мои приложения" (/apps)
2. Нажмите "Создать приложение"
3. Заполните форму:
- Название приложения - отображаемое имя вашего приложения
- Описание - краткое описание (необязательно)
- Redirect URI - URL, на который будет перенаправлен пользователь после авторизации
Шаг 3: Сохранение учетных данных
После создания приложения вы получите:
- Client ID - публичный идентификатор приложения
- Client Secret - секретный ключ (показывается только один раз!)
- Redirect URI - ваш настроенный redirect URI
⚠️ ВАЖНО: Сохраните Client Secret в безопасном месте! Он больше не будет показан.
---
OAuth 2.0 Flow
B4ID использует стандартный Authorization Code Flow согласно спецификации OAuth 2.0.
Схема потока авторизации
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ Клиент │ │ B4ID │ │ Пользователь│
│ (Ваше прил.)│ │ Сервер │ │ │
└──────┬──────┘ └──────┬───────┘ └──────┬──────┘
│ │ │
│ 1. Redirect на │ │
│ /oauth/authorize │ │
├──────────────────────>│ │
│ │ │
│ │ 2. Показ страницы │
│ │ авторизации │
│ ├───────────────────────>│
│ │ │
│ │ 3. Пользователь │
│ │ авторизуется │
│ │<───────────────────────┤
│ │ │
│ │ 4. Согласие на доступ │
│ │<───────────────────────┤
│ │ │
│ 5. Redirect с code │ │
│<──────────────────────┤ │
│ │ │
│ 6. POST /oauth/token │ │
│ (обмен code) │ │
├──────────────────────>│ │
│ │ │
│ 7. Access Token │ │
│<──────────────────────┤ │
│ │ │
│ 8. GET /oauth/userinfo│ │
│ (получение данных) │ │
├──────────────────────>│ │
│ │ │
│ 9. Данные пользователя│ │
│<──────────────────────┤ │
│ │ │
Подробное описание шагов
#### Шаг 1: Перенаправление на страницу авторизации
Перенаправьте пользователя на endpoint авторизации:
GET https://id.b4flow.ru/oauth/authorize?response_type=code&client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&state=RANDOM_STATE
Параметры:
response_type (обязательный) - всегда codeclient_id (обязательный) - ваш Client IDredirect_uri (обязательный) - ваш Redirect URI (должен точно совпадать с зарегистрированным)state (рекомендуется) - случайная строка для защиты от CSRF атакscope (необязательный) - запрашиваемые права доступаПример:
https://id.b4flow.ru/oauth/authorize?response_type=code&client_id=b4id_abc123&redirect_uri=https://myapp.com/callback&state=xyz789
#### Шаг 2: Пользователь авторизуется
Пользователь увидит страницу входа B4ID, где может:
#### Шаг 3: Согласие на доступ
После авторизации пользователь увидит страницу согласия, где указано, какие данные будет запрашивать ваше приложение.
#### Шаг 4: Получение authorization code
После согласия пользователь будет перенаправлен на ваш redirect_uri с параметрами:
code - authorization code (действителен 10 минут)state - ваш параметр state (если был передан)Пример ответа:
https://myapp.com/callback?code=abc123def456&state=xyz789
#### Шаг 5: Обмен code на access token
Отправьте POST запрос на endpoint токенов:
POST https://id.b4flow.ru/oauth/token
Content-Type: application/x-www-form-urlencodedgrant_type=authorization_code&code=AUTHORIZATION_CODE&client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET&redirect_uri=YOUR_REDIRECT_URI
Успешный ответ:
json
{
"access_token": "abc123def456...",
"token_type": "bearer",
"expires_in": 2592000,
"refresh_token": "xyz789uvw012...",
"scope": ""
}
#### Шаг 6: Получение данных пользователя
Используйте access token для получения информации о пользователе:
GET https://id.b4flow.ru/oauth/userinfo
Authorization: Bearer YOUR_ACCESS_TOKEN
Успешный ответ:
json
{
"id": "1",
"username": "john_doe",
"email": "john@example.com",
"display_name": "John Doe",
"first_name": "John",
"last_name": "Doe",
"avatar_url": "https://...",
"created_at": "2024-01-01T00:00:00.000Z"
}
#### Шаг 7: Обновление access token (опционально)
Если access token истек, используйте refresh token:
POST https://id.b4flow.ru/oauth/token
Content-Type: application/x-www-form-urlencodedgrant_type=refresh_token&refresh_token=YOUR_REFRESH_TOKEN&client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET
---
API Endpoints
Base URL
https://id.b4flow.ru
Endpoints
#### 1. Authorization Endpoint
GET /oauth/authorize
Параметры запроса:
response_typecodeclient_idredirect_uristatescopeПример:
GET /oauth/authorize?response_type=code&client_id=b4id_abc123&redirect_uri=https://myapp.com/callback&state=xyz789
#### 2. Token Endpoint
POST /oauth/token
Content-Type: application/x-www-form-urlencoded
Для получения access token:
grant_type=authorization_code
code=AUTHORIZATION_CODE
client_id=YOUR_CLIENT_ID
client_secret=YOUR_CLIENT_SECRET
redirect_uri=YOUR_REDIRECT_URI
Для обновления access token:
grant_type=refresh_token
refresh_token=YOUR_REFRESH_TOKEN
client_id=YOUR_CLIENT_ID
client_secret=YOUR_CLIENT_SECRET
Успешный ответ (200 OK):
json
{
"access_token": "abc123def456...",
"token_type": "bearer",
"expires_in": 2592000,
"refresh_token": "xyz789uvw012...",
"scope": ""
}
Ошибки:
json
{
"error": "invalid_grant",
"error_description": "Invalid or expired authorization code"
}
#### 3. UserInfo Endpoint
GET /oauth/userinfo
Authorization: Bearer YOUR_ACCESS_TOKEN
Успешный ответ (200 OK):
json
{
"id": "1",
"username": "john_doe",
"email": "john@example.com",
"display_name": "John Doe",
"first_name": "John",
"last_name": "Doe",
"avatar_url": "https://...",
"created_at": "2024-01-01T00:00:00.000Z"
}
Ошибка (401 Unauthorized):
json
{
"error": "invalid_token",
"error_description": "Invalid or expired access token"
}
#### 4. Revoke Token Endpoint
POST /oauth/revoke
Content-Type: application/x-www-form-urlencodedtoken=ACCESS_TOKEN_OR_REFRESH_TOKEN
Успешный ответ (200 OK):
json
{
"revoked": true
}
---
Примеры интеграции
JavaScript (Frontend + Backend)
#### Шаг 1: Перенаправление на авторизацию
javascript
// Генерируем случайный state для защиты от CSRF
const state = Math.random().toString(36).substring(7);// Сохраняем state в sessionStorage
sessionStorage.setItem('oauth_state', state);
// Перенаправляем пользователя
const authUrl = new URL('https://id.b4flow.ru/oauth/authorize');
authUrl.searchParams.set('response_type', 'code');
authUrl.searchParams.set('client_id', 'YOUR_CLIENT_ID');
authUrl.searchParams.set('redirect_uri', 'https://myapp.com/callback');
authUrl.searchParams.set('state', state);
window.location.href = authUrl.toString();
#### Шаг 2: Обработка callback
javascript
// На странице /callback
const urlParams = new URLSearchParams(window.location.search);
const code = urlParams.get('code');
const state = urlParams.get('state');
const error = urlParams.get('error');// Проверяем state
const savedState = sessionStorage.getItem('oauth_state');
if (state !== savedState) {
console.error('Invalid state parameter');
return;
}
sessionStorage.removeItem('oauth_state');
// Проверяем на ошибки
if (error) {
console.error('OAuth error:', error);
return;
}
// Отправляем code на ваш backend для обмена на token
fetch('/api/auth/b4id', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ code })
})
.then(response => response.json())
.then(data => {
// Сохраняем токены
localStorage.setItem('access_token', data.access_token);
localStorage.setItem('refresh_token', data.refresh_token);
// Перенаправляем на главную страницу
window.location.href = '/';
})
.catch(error => {
console.error('Error:', error);
});
#### Шаг 3: Backend - обмен code на token
javascript
// Node.js/Express пример
app.post('/api/auth/b4id', async (req, res) => {
const { code } = req.body;
try {
// Обмениваем code на access token
const tokenResponse = await fetch('https://id.b4flow.ru/oauth/token', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: new URLSearchParams({
grant_type: 'authorization_code',
code: code,
client_id: process.env.B4ID_CLIENT_ID,
client_secret: process.env.B4ID_CLIENT_SECRET,
redirect_uri: 'https://myapp.com/callback'
})
});
const tokens = await tokenResponse.json();
if (tokens.error) {
return res.status(400).json({ error: tokens.error_description });
}
// Получаем информацию о пользователе
const userResponse = await fetch('https://id.b4flow.ru/oauth/userinfo', {
headers: {
'Authorization': Bearer ${tokens.access_token}
}
});
const user = await userResponse.json();
// Сохраняем пользователя в вашу базу данных
// Создаем сессию
// ...
res.json({
access_token: tokens.access_token,
refresh_token: tokens.refresh_token,
user: user
});
} catch (error) {
console.error('OAuth error:', error);
res.status(500).json({ error: 'Internal server error' });
}
});
#### Шаг 4: Получение данных пользователя
javascript
// Использование access token
async function getUserInfo() {
const accessToken = localStorage.getItem('access_token');
const response = await fetch('https://id.b4flow.ru/oauth/userinfo', {
headers: {
'Authorization': Bearer ${accessToken}
}
});
if (response.status === 401) {
// Token истек, обновляем его
await refreshAccessToken();
return getUserInfo();
}
return await response.json();
}// Обновление access token
async function refreshAccessToken() {
const refreshToken = localStorage.getItem('refresh_token');
const response = await fetch('https://id.b4flow.ru/oauth/token', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: new URLSearchParams({
grant_type: 'refresh_token',
refresh_token: refreshToken,
client_id: 'YOUR_CLIENT_ID',
client_secret: 'YOUR_CLIENT_SECRET'
})
});
const tokens = await response.json();
if (tokens.access_token) {
localStorage.setItem('access_token', tokens.access_token);
if (tokens.refresh_token) {
localStorage.setItem('refresh_token', tokens.refresh_token);
}
} else {
// Refresh token истек, нужно авторизоваться заново
window.location.href = '/login';
}
}
Python (Flask)
python
from flask import Flask, redirect, request, session, url_for
import requests
import secretsapp = Flask(__name__)
app.secret_key = 'your-secret-key'
B4ID_CLIENT_ID = 'your_client_id'
B4ID_CLIENT_SECRET = 'your_client_secret'
B4ID_REDIRECT_URI = 'https://myapp.com/callback'
B4ID_AUTH_URL = 'https://id.b4flow.ru/oauth/authorize'
B4ID_TOKEN_URL = 'https://id.b4flow.ru/oauth/token'
B4ID_USERINFO_URL = 'https://id.b4flow.ru/oauth/userinfo'
@app.route('/login')
def login():
# Генерируем state
state = secrets.token_urlsafe(32)
session['oauth_state'] = state
# Строим URL авторизации
auth_url = f"{B4ID_AUTH_URL}?response_type=code&client_id={B4ID_CLIENT_ID}&redirect_uri={B4ID_REDIRECT_URI}&state={state}"
return redirect(auth_url)
@app.route('/callback')
def callback():
code = request.args.get('code')
state = request.args.get('state')
error = request.args.get('error')
# Проверяем state
if state != session.get('oauth_state'):
return 'Invalid state parameter', 400
if error:
return f'OAuth error: {error}', 400
# Обмениваем code на token
token_data = {
'grant_type': 'authorization_code',
'code': code,
'client_id': B4ID_CLIENT_ID,
'client_secret': B4ID_CLIENT_SECRET,
'redirect_uri': B4ID_REDIRECT_URI
}
token_response = requests.post(B4ID_TOKEN_URL, data=token_data)
tokens = token_response.json()
if 'error' in tokens:
return f'Token error: {tokens["error_description"]}', 400
# Сохраняем токены в сессии
session['access_token'] = tokens['access_token']
session['refresh_token'] = tokens['refresh_token']
# Получаем информацию о пользователе
headers = {'Authorization': f"Bearer {tokens['access_token']}"}
user_response = requests.get(B4ID_USERINFO_URL, headers=headers)
user = user_response.json()
# Сохраняем пользователя в базу данных
# ...
return redirect(url_for('dashboard'))
@app.route('/userinfo')
def userinfo():
access_token = session.get('access_token')
if not access_token:
return redirect(url_for('login'))
headers = {'Authorization': f'Bearer {access_token}'}
response = requests.get(B4ID_USERINFO_URL, headers=headers)
if response.status_code == 401:
# Token истек, обновляем
refresh_token = session.get('refresh_token')
if refresh_token:
token_data = {
'grant_type': 'refresh_token',
'refresh_token': refresh_token,
'client_id': B4ID_CLIENT_ID,
'client_secret': B4ID_CLIENT_SECRET
}
token_response = requests.post(B4ID_TOKEN_URL, data=token_data)
tokens = token_response.json()
if 'access_token' in tokens:
session['access_token'] = tokens['access_token']
return redirect(url_for('userinfo'))
return redirect(url_for('login'))
return response.json()
PHP
php
define('B4ID_CLIENT_ID', 'your_client_id');
define('B4ID_CLIENT_SECRET', 'your_client_secret');
define('B4ID_REDIRECT_URI', 'https://myapp.com/callback');
define('B4ID_AUTH_URL', 'https://id.b4flow.ru/oauth/authorize');
define('B4ID_TOKEN_URL', 'https://id.b4flow.ru/oauth/token');
define('B4ID_USERINFO_URL', 'https://id.b4flow.ru/oauth/userinfo');
// Страница входа
function login() {
$state = bin2hex(random_bytes(16));
$_SESSION['oauth_state'] = $state;
$authUrl = B4ID_AUTH_URL . '?' . http_build_query([
'response_type' => 'code',
'client_id' => B4ID_CLIENT_ID,
'redirect_uri' => B4ID_REDIRECT_URI,
'state' => $state
]);
header('Location: ' . $authUrl);
exit;
}
// Callback обработчик
function callback() {
$code = $_GET['code'] ?? null;
$state = $_GET['state'] ?? null;
$error = $_GET['error'] ?? null;
// Проверяем state
if ($state !== $_SESSION['oauth_state']) {
die('Invalid state parameter');
}
if ($error) {
die('OAuth error: ' . $error);
}
// Обмениваем code на token
$tokenData = [
'grant_type' => 'authorization_code',
'code' => $code,
'client_id' => B4ID_CLIENT_ID,
'client_secret' => B4ID_CLIENT_SECRET,
'redirect_uri' => B4ID_REDIRECT_URI
];
$ch = curl_init(B4ID_TOKEN_URL);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($tokenData));
$response = curl_exec($ch);
curl_close($ch);
$tokens = json_decode($response, true);
if (isset($tokens['error'])) {
die('Token error: ' . $tokens['error_description']);
}
// Сохраняем токены
$_SESSION['access_token'] = $tokens['access_token'];
$_SESSION['refresh_token'] = $tokens['refresh_token'];
// Получаем информацию о пользователе
$ch = curl_init(B4ID_USERINFO_URL);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $tokens['access_token']
]);
$userResponse = curl_exec($ch);
curl_close($ch);
$user = json_decode($userResponse, true);
// Сохраняем пользователя
// ...
header('Location: /dashboard');
exit;
}
// Получение информации о пользователе
function getUserInfo() {
if (!isset($_SESSION['access_token'])) {
header('Location: /login');
exit;
}
$ch = curl_init(B4ID_USERINFO_URL);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $_SESSION['access_token']
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode === 401) {
// Token истек, обновляем
// ... код обновления токена
header('Location: /login');
exit;
}
return json_decode($response, true);
}
?>
---
Часто задаваемые вопросы
Как долго действует access token?
Access token действителен 30 дней (2,592,000 секунд).
Как долго действует refresh token?
Refresh token действителен 1 год (31,536,000 секунд).
Как долго действует authorization code?
Authorization code действителен 10 минут (600 секунд).
Что делать, если access token истек?
Используйте refresh token для получения нового access token через endpoint /oauth/token с grant_type=refresh_token.
Что делать, если refresh token истек?
Пользователю нужно авторизоваться заново через процесс OAuth.
Можно ли использовать несколько redirect URI?
Нет, каждое приложение имеет один redirect URI, который должен точно совпадать с указанным при создании приложения.
Поддерживается ли PKCE?
В текущей версии PKCE не поддерживается. Используется стандартный Authorization Code Flow с client_secret.
Какие данные доступны через UserInfo API?
id - уникальный идентификатор пользователяusername - имя пользователяemail - email адресdisplay_name - отображаемое имяfirst_name - имяlast_name - фамилияavatar_url - URL аватараcreated_at - дата регистрацииКак отозвать токен?
Используйте endpoint /oauth/revoke для отзыва access token или refresh token.
---
Безопасность
Рекомендации
1. Никогда не раскрывайте Client Secret - используйте его только на сервере 2. Используйте HTTPS - все запросы должны идти по защищенному протоколу 3. Проверяйте state параметр - для защиты от CSRF атак 4. Храните токены безопасно - используйте безопасное хранилище (не localStorage для production) 5. Обновляйте токены - используйте refresh token до истечения access token 6. Валидируйте redirect_uri - убедитесь, что redirect_uri совпадает с зарегистрированным
Обработка ошибок
Всегда обрабатывайте возможные ошибки:
invalid_request - отсутствуют обязательные параметрыinvalid_client - неверный client_id или client_secretinvalid_grant - неверный или истекший authorization codeaccess_denied - пользователь отказал в доступеinvalid_token - неверный или истекший access tokenserver_error - внутренняя ошибка сервера---
Поддержка
Если у вас возникли вопросы или проблемы при интеграции:
1. Проверьте эту документацию 2. Убедитесь, что вы следуете OAuth 2.0 спецификации 3. Проверьте логи вашего приложения и сервера B4ID
---
Версия документации: 1.0 Последнее обновление: 2024-12-25