Вхід через TTAR
Авторизація за акаунтом TTAR на вашому сайті або в застосунку: гравці входять в один клік, а ви одразу бачите їхній рейтинг.
Якщо у вас є сайт або застосунок для любителів настільного тенісу — клуб, турніри, тренування, магазин інвентарю, — підключіть «Вхід через TTAR». Гравці зможуть авторизуватися у вас своїм акаунтом TTAR в один клік, як через Google або Telegram, без нового логіна й пароля. А ви одразу дізнаєтеся, хто до вас прийшов і наскільки сильно він грає.
Що це дає вашому сервісу:
- Більше реєстрацій. Не треба заповнювати анкету й підтверджувати пошту: гравець входить своїм логіном TTAR, тож менше людей кидають реєстрацію на півдорозі.
- Рейтинг гравця одразу. Разом з авторизацією ви отримуєте рейтинг TTAR: за ним зручно провести посів турніру, розбити учасників на групи за силою, підібрати спаринг-партнера або перевірити допуск до змагання.
- Власна авторизація не потрібна. Зберігання паролів, відновлення доступу, вхід через Google і Telegram — усе це вже працює в TTAR. Розробникам достатньо підключити стандартний протокол OpenID Connect: готові бібліотеки для нього є в усіх популярних мовах програмування.
- Безпечно для гравців. Пароля від TTAR ви ніколи не отримуєте: гравець вводить його лише на сторінці TTAR. Вам передаються тільки ті дані, які ви запросили, — ID гравця, ім'я та аватар, email і рейтинг.
Нижче — технічний опис. Цю сторінку можна одразу передати розробникам.
Параметри сервера авторизації
Більшості OIDC-бібліотек достатньо вказати Issuer: решту адрес вони прочитають із discovery-документа.
Issuer https://stage.api.ttar.app Discovery https://stage.api.ttar.app/.well-known/openid-configuration Authorization https://stage.api.ttar.app/connect/authorize Token https://stage.api.ttar.app/connect/token UserInfo https://stage.api.ttar.app/connect/userinfo End session https://stage.api.ttar.app/connect/logout JWKS https://stage.api.ttar.app/.well-known/jwks
Реєстрація клієнта
Кожному партнерові видається client_id. Секрет не використовується — підтримується лише PKCE (code_challenge_method=S256). Щоб зареєструватися, напишіть нам на kot@ttar.app.
Під час реєстрації ви повідомляєте один або кілька redirect_uri — адрес у вашому застосунку, куди ми перенаправлятимемо користувача після авторизації. Ми вносимо їх до білого списку. У кожному запиті ви вказуєте конкретну адресу, і сервер звіряє її з цим списком.
Додатково можна повідомити один або кілька post_logout_redirect_uri — куди повернути користувача після виходу через наш end-session endpoint /connect/logout (див. розділ «Вихід» нижче). Це окремий білий список: redirect_uri як адреса повернення після виходу не приймається. Він потрібен, лише якщо ви користуєтеся цим виходом.
Вхід: Authorization Code + PKCE
Крок 1. Спрямуйте користувача на авторизацію. Сформуйте посилання й відкрийте його в браузері користувача повним переходом, не в iframe:
GET https://stage.api.ttar.app/connect/authorize ?client_id=YOUR_CLIENT_ID &response_type=code &redirect_uri=https://yourapp.com/callback &scope=openid profile email ttar:rating &code_challenge=BASE64URL(SHA256(code_verifier)) &code_challenge_method=S256 &state=RANDOM_OPAQUE_VALUE
Якщо користувач ще не ввійшов до TTAR у цьому браузері, він потрапляє на сторінку входу TTAR і входить. Якщо активна сесія TTAR уже є, сторінка входу пропускається й код видається одразу (single sign-on) — хіба що ви запросили повторний вхід через prompt=login. Необов'язкові параметри prompt і max_age описано в розділі «Повторний вхід і зміна акаунта» нижче.
Крок 2. Прийміть відповідь на redirect_uri. Після успішного входу браузер користувача автоматично перенаправляється на ваш redirect_uri із двома параметрами:
GET https://yourapp.com/callback?code=AUTHORIZATION_CODE&state=RANDOM_OPAQUE_VALUE
code— одноразовий код авторизації. Він дійсний близько 60 секунд, тож використайте його одразу.state— те саме значення, що ви передали на кроці 1. Обов'язково звірте його зі збереженим у себе: це захист від CSRF.
Якщо користувач відмовив або сталася помилка, прийде:
GET https://yourapp.com/callback?error=access_denied&error_description=...&state=...
Крок 3. Обміняйте код на токени. На сервері, не в браузері, надішліть POST із кодом з кроку 2:
POST https://stage.api.ttar.app/connect/token Content-Type: application/x-www-form-urlencoded grant_type=authorization_code &client_id=YOUR_CLIENT_ID &code=AUTHORIZATION_CODE &redirect_uri=https://yourapp.com/callback &code_verifier=YOUR_CODE_VERIFIER
redirect_uri тут має збігатися з тим, який передавали на кроці 1: сервер використовує його як додаткову перевірку.Відповідь:
{
"access_token": "...",
"id_token": "...",
"refresh_token": "...",
"token_type": "Bearer",
"expires_in": 3600
}
access_token— Bearer-токен для звернень до API, зокрема до/connect/userinfo. Це JWT, підписаний RS256.id_token— JWT з базовою інформацією про користувача:sub, ім'я, email тощо. Підпис перевіряйте обов'язково.refresh_token— щоб отримувати нові токени без повторного входу. Видається, лише якщо запитано scopeoffline_access.
Крок 4. Оновлюйте токени. Коли термін дії access token спливає, отримайте нові токени за допомогою refresh token:
POST https://stage.api.ttar.app/connect/token Content-Type: application/x-www-form-urlencoded grant_type=refresh_token &client_id=YOUR_CLIENT_ID &refresh_token=REFRESH_TOKEN
Scopes
| Scope | Що повертає |
|---|---|
openid | sub (ID гравця в TTAR). Обов'язковий. |
profile | name, picture (URL аватара) |
email | email, email_verified |
offline_access | Додає refresh_token до відповіді token endpoint /connect/token. Без цього scope refresh token не видається. |
ttar:rating | Claim ttar_rating в access token — масив рейтингів гравця (див. нижче). |
Claim ttar_rating
Якщо запитано scope ttar:rating і в гравця є рейтинг, в access token з'являється claim ttar_rating. Це JSON-масив, по одному об'єкту на кожну руку — основну та неосновну:
[
{
"handType": "Main",
"rating": 1456,
"games": 120,
"qualificationPoints": 85,
"isRated": true
},
{
"handType": "Weak",
"rating": 1102,
"games": 15,
"qualificationPoints": 10,
"isRated": false
}
]
Інші дані (ім'я, аватар, email) доступні через UserInfo endpoint /connect/userinfo або в id_token.
Повторний вхід і зміна акаунта
TTAR підтримує в браузері користувача сесію single sign-on (SSO) — cookie на домені TTAR API. Поки вона активна, /connect/authorize видає код для того самого користувача TTAR, не показуючи сторінки входу. Ця сесія не залежить від сесії вашого застосунку: вихід користувача з вашого застосунку її не завершує.
prompt=login— завжди показує сторінку входу TTAR і вимагає ввійти знову, навіть за активної сесії: наявна сесія TTAR повторно не використовується. Користувач може ввійти в інший акаунт TTAR. Рекомендовано для прив'язки акаунта.prompt=select_account— те саме, щоprompt=login. Вибору акаунта в TTAR немає: користувач обирає акаунт, входячи в нього.prompt=none— ніколи не показує інтерфейсу. Якщо активної сесії немає або вона старша заmax_age, користувач повертається на вашredirect_uriзerror=login_required.prompt=consent— приймається і ні на що не впливає: зареєстрованих партнерів схвалено заздалегідь, екрана згоди в TTAR немає.max_age=N— якщо користувач входив більш ніжNсекунд тому, йому доведеться ввійти знову.max_age=0— те саме, щоprompt=login.
Некоректний prompt (невідоме значення або none разом з іншим значенням) TTAR відхиляє з HTTP 400 — браузер не повертається на ваш redirect_uri.
Claim auth_time. У id_token є auth_time — Unix-час у секундах останнього інтерактивного входу користувача до TTAR: за email і паролем, через Google або Telegram. Під час оновлення токенів він не змінюється. Його може не бути лише в сесіях TTAR, розпочатих до появи цієї функції. Така сесія ніколи не задовольняє умов prompt=login і max_age і завжди встановлюється заново, тому з будь-яким із цих параметрів id_token обов'язково містить auth_time.
Прив'язка акаунта TTAR:
- Додайте до запиту авторизації
prompt=loginі запам'ятайте момент, коли ви його розпочали. - Після обміну коду перевірте, що
auth_timeне раніше за цей момент, із запасом у кілька секунд на розбіжність годинників. Так ви переконаєтеся, що користувач справді ввійшов у межах цього запиту, а не було повторно використано наявну сесію. - Прив'язуйте за
sub— ID гравця в TTAR.
auth_time його відображає.Щоб користувач міг прив'язати інший акаунт TTAR, виходити не потрібно — достатньо prompt=login.
Вихід
Вихід користувача з вашого застосунку не завершує його сесії TTAR. Якщо потрібно завершити і її в цьому браузері (наприклад, «вийти скрізь» або спільний комп'ютер), спрямуйте браузер користувача на end-session endpoint /connect/logout повним переходом сторінки. XHR та iframe не підійдуть: cookie сесії належить домену TTAR.
GET https://stage.api.ttar.app/connect/logout ?client_id=YOUR_CLIENT_ID &post_logout_redirect_uri=https://yourapp.com/logged-out &state=RANDOM_OPAQUE_VALUE &id_token_hint=ID_TOKEN
- TTAR видаляє cookie своєї сесії й перенаправляє браузер на
post_logout_redirect_uri, додавши до ньогоstate. post_logout_redirect_uriмає бути зареєстрований заздалегідь. Потрібен точний збіг, і це окремий список, неredirect_uri(див. «Реєстрація клієнта»). З незареєстрованою адресою TTAR відхиляє весь запит з HTTP 400 — і сесія не завершується.- Без
post_logout_redirect_uriсесія завершується, але користувач не повертається до вашого застосунку. id_token_hintнеобов'язковий. Якщо ви його передаєте, це має бутиid_token, виданий вашомуclient_id. Прострочений теж підійде.- Вихід завершує сесію TTAR користувача в цьому браузері для всіх сервісів, де підключено «Вхід через TTAR», а не лише для вашого.
Перевірка токенів
Токени підписані RS256. Публічні ключі — за стандартною адресою JWKS:
https://stage.api.ttar.app/.well-known/jwks
Будь-яка стандартна OIDC-бібліотека підхопить їх автоматично через discovery endpoint. Перевіряйте:
- підпис:
alg=RS256, ключ із JWKS; iss=https://stage.api.ttar.app;aud= вашclient_id;exp: термін дії токена не сплив;auth_time, якщо ви використовуєтеprompt=loginабоmax_age(див. «Claim auth_time» вище).
Важливо для staging
- Staging — тестове середовище для ваших експериментів.
- Акаунт для тестів надається окремо.
- Після переходу на продакшн
client_idзалишиться тим самим, зміниться лише Issuer — наhttps://api.ttar.app.