Контекст-токен
Ваша страница работает в браузере человека, поэтому всё, что она говорит о «кто я», можно подделать. Когда вашему серверу нужно знать, кто открыл приложение, — чтобы сохранить результат, списать деньги или дать доступ, — используйте контекст-токен.
app.contextToken — это JWT, подписанный ReMeet (RS256). ReMeet выдаёт новый при каждом запуске рамки приложения.
Что внутри
{
"iss": "https://remeet.video",
"aud": "your-app-key",
"sub": "p_3f9c0a7d51e2b84c6a0d9e17",
"name": "Анна Иванова",
"room": "01m6saztdr6cafg9yzx83db0fs",
"role": "host",
"surface": "panel",
"locale": "ru",
"iat": 1794067200,
"exp": 1794067800,
"jti": "1b4e28ba-2fa1-11d2-883f-0016d3cca427"
}| Поле | Что значит |
|---|---|
iss | Всегда https://remeet.video. |
aud | key вашего приложения. Токены для других приложений отклоняйте. |
sub | id участника для вашего приложения — тот же, что app.me.id. Одинаковый у одного человека во всех встречах. |
name | Имя человека во встрече. |
room | id встречи — тот же, что app.context.meeting.id. |
role | host, member или guest. |
surface | panel или stage. |
locale | en, ru или ar. |
iat, exp | Когда выдан и когда истекает (секунды Unix). Токен живёт 10 минут. |
jti | Уникальный id токена: запоминайте использованные, если нужно защититься от повторов. |
Проверка на сервере
Открытые ключи: remeet.video/.well-known/jwks.json. Ключ выбирается по kid из заголовка токена; набор ключей кешируйте — он меняется редко.
import { createRemoteJWKSet, jwtVerify } from 'jose';
const jwks = createRemoteJWKSet(new URL('https://remeet.video/.well-known/jwks.json'));
export async function verifyReMeet(token) {
const { payload } = await jwtVerify(token, jwks, {
issuer: 'https://remeet.video',
audience: 'your-app-key',
algorithms: ['RS256'],
});
return payload; // { sub, name, room, role, … }
}import jwt
jwks = jwt.PyJWKClient("https://remeet.video/.well-known/jwks.json")
def verify_remeet(token: str) -> dict:
key = jwks.get_signing_key_from_jwt(token)
return jwt.decode(
token,
key.key,
algorithms=["RS256"],
audience="your-app-key",
issuer="https://remeet.video",
)use Firebase\JWT\JWK;
use Firebase\JWT\JWT;
function verifyReMeet(string $token): object
{
$jwks = json_decode(file_get_contents('https://remeet.video/.well-known/jwks.json'), true);
$claims = JWT::decode($token, JWK::parseKeySet($jwks));
if ($claims->iss !== 'https://remeet.video' || $claims->aud !== 'your-app-key') {
throw new RuntimeException('Not a token for this app');
}
return $claims;
}Обычная схема
Приложение стартует:
const app = await ReMeet.ready().Один раз отправляет
app.contextTokenна ваш сервер:jsconst response = await fetch('https://api.your-site.example/session', { method: 'POST', headers: { Authorization: `Bearer ${app.contextToken}` }, });Сервер проверяет токен и отвечает своей сессией (cookie или собственным токеном), которая живёт столько, сколько вам нужно.
10 минут жизни — для этого обмена, а не на всю встречу. Новый токен приходит, когда рамка запускается снова (человек заново открыл панель или перезагрузил страницу).
CORS
Ваш API вызывается с origin вашей же страницы (адрес рамки), а не с remeet.video. Разрешите этот origin в CORS.