Авторизация запросов
При работе со SaluteJazz API вам понадобятся токены двух видов: транспортный токен и токен доступа.
Создание транспортного токена
Транспортный токен — это JSON Web Token (JWT), подписанный с помощью ключа SDK по алгоритму ECDSA.
Подробнее о ключе SDK
Ключ SDK — закодированный в Base64 объект JSON, который состоит из идентификатора проекта и JWK.
Пример структуры ключа:
{
"projectId": "f98d99c6-072e-4687-867b-a74dc6a22ef8",
"key": {
"kty": "EC",
"d": "mQGSp33ATOo4wPLzzqFm1qKm8OJ5sHD-n3i7r1_NMWQ8UpgC42cscfi5fM4TbKxt",
"use": "enc",
"crv": "P-384",
"kid": "dde4b3b1-2441-4630-b186-9d0faef24891",
"x": "ykJ5V-8YgmaYHzV165B73EhPatGoxYJ0zP4bmof3hH6qHg1p-UY4q1FZqJHbbF_x",
"y": "06HfHcopKbJNNEFcKYUiQgXJN239f-0zOgzd0Okx-aL9kxMR2DvFJqfn9fz-3OH-"
}
}
Полезная нагрузка транспортного токена включает обязательные поля:
- Описание
- Пример
Вы можете передавать в полезной нагрузке различные необязательные поля вроде имени пользователя, адреса электронной почты и других.
С помощью одного транспортного токена вы можете выпустить неограниченного количество токенов доступа с различными параметрами (сроком действия, идентификатором, данными пользователя и другими).
Для создания транспортного токена:
- Выпустите ключ SaluteJazz SDK.
- Добавьте логику, с помощью которой приложение будет генерировать транспортный токен в соответствии с форматом JWT.
- Зашифруйте данные по алгоритму AES256 и подпишите их с помощью ключа SaluteJazz SDK по алгоритму ECDSA.
Пример создания транспортного токена в SaluteJazz SDK для Web
Вы можете создать транспортный токен с помощью утилиты SaluteJazz SDK для Web.
Для создания транспортного токена:
Выпустите ключ SaluteJazz SDK.
Декодируйте ключ из base64 в
object
.export function parseSecret(key: Base64String): SecretResult {
let result: SecretResult;
try {
result = JSON.parse(decoder.decode(decodeSafeUrl(key)));
} catch (error) {
throw createError('ER_INVALID_KEY', 'Invalid Key');
}
if (!isMatching(SECRET_RESULT_PATTERN, result)) {
throw createError('ER_INVALID_KEY', 'Invalid Key');
}
return result;
}Получите детали алгоритма создания приватного ключа.
const algorithm = recognizeAlgorithm(secret);
Сформируйте полезную нагрузку JWT.
const payload: JWTPayload = {
iat,
exp: iat + expireIn,
jti: requestId,
sdkProjectId: algorithm.projectId,
iss, // Для логов. Не больше 100 символов.
sub, // Идентификатор пользователя в бэкенде приложения
userName: userName, // Необязательно. Используется для отображения в комнате
userEmail: userEmail, // Необязательно
};Сформируйте заголовок JWT.
const header: JWTHeader = {
alg: algorithm.alg,
kid: algorithm.kid,
typ: 'JWT',
};Сформируйте первую часть JWT из заголовка и полезной нагрузки.
const textToSign = headerBase64 + '.' + payloadBase64;
Выпустите приватный ключ с помощью алгоритма криптографии ECDSA.
const privateKey = await importECDSAPrivateKey(algorithm.jwk);
Подпишите первую часть JWT с помощью приватного ключа.
const { signature } = await algorithm.sign(textToSign, privateKey);
Сформируйте итоговый транспортный токен.
const signedJwt = createSignedJWT(textToSign, signature);
Используйте транспортный токен для получения токена доступа.
Примеры кода для создания токена на разных языках
- Python
- Java
- Kotlin
import base64
import datetime
import json
import uuid
import jwt
from jwt import PyJWK
# Разбор ключа SDK
# Ключ содержит идентификатор проекта и JWK, который используется для подписи JWT
sdk_key_encoded = '{значение ключа SDK}'
sdk_key = json.loads(base64.b64decode(sdk_key_encoded))
# В заголовке JWT нужно указать идентификатор ключа и алгоритм подписи
# Алгоритм можно определить по полю kty и другим параметрам ключа sdk_key['key']
# Например, для kty=EC и crv=P-384 следует указывать алгоритм ES384
# Описание алгоритмов и их кодов можно изучить по ссылке https://datatracker.ietf.org/doc/html/rfc7518#section-3.1
jwt_header = {
'typ': 'JWT',
"alg": 'ES384',
'kid': sdk_key['key']['kid'],
}
# Тело JWT
iat = datetime.datetime.utcnow()
exp = iat + datetime.timedelta(hours=1)
jti = str(uuid.uuid4())
jwt_payload = {
"iat": iat,
"exp": exp,
"jti": jti,
"sdkProjectId": sdk_key['projectId'],
# В поле sub нужно передать идентификатор пользователя в бэкенде вашего приложения
# Идентификатор должен соответствовать формату UUID4
"sub": '15eca6c5-fb2d-48f2-804a-f97e542ebd33',
#'userName': 'User Name',
#'userEmail': 'user@email',
}
# Подпись JWT
jwk = PyJWK.from_dict(sdk_key['key'], algorithm='ES384')
jws = jwt.encode(headers=jwt_header, payload=jwt_payload, key=jwk.key, algorithm='ES384')
print(jws) # Вывод строки с транспортным токеном
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.nimbusds.jose.JOSEObjectType;
import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jose.JWSHeader;
import com.nimbusds.jose.JWSObject;
import com.nimbusds.jose.Payload;
import com.nimbusds.jose.crypto.ECDSASigner;
import com.nimbusds.jose.jwk.JWK;
import java.util.Base64;
import java.util.Map;
import java.util.UUID;
public class TransportTokenGenerator {
private static final ObjectMapper objectMapper = new ObjectMapper();
public static String getTransportToken(String sberJazzKey) throws Exception {
// Получает данные из ключа
JsonNode sdkKey = objectMapper.readTree(Base64.getDecoder().decode(sberJazzKey));
// Формирует jws header
// В заголовке JWT нужно указать идентификатор ключа и алгоритм подписи
// Алгоритм можно определить по полю kty и другим параметрам ключа key['key']
// Например, для kty=EC и crv=P-384 следует указывать алгоритм ES384
// Описание алгоритмов и их кодов можно изучить по ссылке https://datatracker.ietf.org/doc/html/rfc7518#section-3.1
JWSHeader header = new JWSHeader.Builder(JWSAlgorithm.ES384)
.keyID(sdkKey.get("key").get("kid").asText())
.type(JOSEObjectType.JWT)
.build();
// Формирует payload jws токена
long currentTimeSeconds = System.currentTimeMillis() / 1000L;
Payload payload = new Payload(Map.of(
"iat", currentTimeSeconds,
"exp", currentTimeSeconds + 3600,
"jti", UUID.randomUUID().toString(),
"sdkProjectId", sdkKey.get("projectId").asText(),
// Идентификатор для логов. Не больше 100 символов
"iss", UUID.randomUUID().toString(),
// В поле sub нужно передать идентификатор пользователя в бэкенде вашего приложения
// Идентификатор должен соответствовать формату UUID4
"sub", UUID.randomUUID().toString(),
"userName", "userName", // Отображается во время видеовстречи
"userEmail", "userEmail@jazz.com"
));
JWSObject JWS = new JWSObject(header, payload);
// Подписывает токен
ECDSASigner signer = new ECDSASigner(JWK.parse(sdkKey.get("key").toString()).toECKey());
JWS.sign(signer);
return JWS.serialize();
}
}
import com.fasterxml.jackson.databind.JsonNode
import com.fasterxml.jackson.databind.ObjectMapper
import com.nimbusds.jose.crypto.ECDSASigner
import com.nimbusds.jose.JWSAlgorithm
import com.nimbusds.jose.JWSHeader
import com.nimbusds.jose.JOSEObjectType
import com.nimbusds.jose.JWSObject
import com.nimbusds.jose.jwk.JWK
import com.nimbusds.jose.Payload
import java.util.Base64
import java.util.UUID
class TransportTokenGenerator {
private val objectMapper = ObjectMapper()
fun getTransportToken(sberJazzKey: String): String {
// Получает данные из ключа
val key: JsonNode = objectMapper.readTree(Base64.getDecoder().decode(sberJazzKey))
// Формирует jws header
// В заголовке JWT нужно указать идентификатор ключа и алгоритм подписи
// Алгоритм можно определить по полю kty и другим параметрам ключа key['key']
// Например, для kty=EC и crv=P-384 следует указывать алгоритм ES384
// Описание алгоритмов и их кодов можно изучить по ссылке https://datatracker.ietf.org/doc/html/rfc7518#section-3.1
val header = JWSHeader.Builder(JWSAlgorithm.ES384)
.keyID(key["key"]["kid"].asText())
.type(JOSEObjectType.JWT)
.build()
// Формирует payload jws токена
val payload = Payload(
mapOf(
"iat" to System.currentTimeMillis() / 1000,
"exp" to System.currentTimeMillis() / 1000 + 10000,
"jti" to UUID.randomUUID().toString(),
"sdkProjectId" to key["projectId"].asText(),
// Идентификатор для логов. Не больше 100 символов
"iss" to "iss",
// В поле sub нужно передать идентификатор пользователя в бэкенде вашего приложения
// Идентификатор должен соответствовать формату UUID4
"sub" to "sub",
// Отображается во время видеовстречи
"userName" to "userName",
"userEmail" to "userEmail",
)
)
val jws = JWSObject(header, payload)
// Подписывает токен
val signer = ECDSASigner(JWK.parse(key["key"].toString()).toECKey())
jws.sign(signer)
return jws.serialize()
}
}
Создание тестового транспортного токена
С помощью формы вы можете создать тестовый транспортный токен. Токен действует в течение 30 минут. Для создания тестового токена потребуется ключ SaluteJazz SDK.
В целях безопасности для создания тестового токена используйте отдельный ключ SDK, который не будет применяться в эксплуатационной среде.
для тестирования запросов
Получение токена доступа
Токен доступа нужен для авторизации запросов к SaluteJazz API.
Для получения токена доступа передайте запрос -запрос по адресу POST /v1/auth/login
:
curl -L -X POST 'https://api.salutejazz.ru/v1/auth/login' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer <транспортный_токен>'
Адрес API изменился на https://api.salutejazz.ru/v1
.
Подробнее об изменении домена.
В ответ вы получите строку с токеном доступа:
- Пример
- Описание
Авторизация запросов
Используйте токен доступа для авторизации запросов к SaluteJazz API, например, для создания комнаты (запрос POST /room/create
):
curl -L -X POST 'https://api.salutejazz.ru/v1/room/create' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer <токен_доступа>' \
--data-raw '{
"roomTitle": "Мастер-класс"
}'
Адрес API изменился на https://api.salutejazz.ru/v1
.
Подробнее об изменении домена.