トークンは、クラウドサービスへの不正なアクセスを防ぐためのセキュリティ署名です。トークンはサーバー上で生成し、クライアント SDK に配布します。クライアント SDK は、このトークンを使用してチャネルに参加します。
前提条件
-
Alibaba Cloud アカウントをお持ちで、ApsaraVideo Live サービスが有効化されていること。
-
ARTC アプリケーションを作成し、AppID と AppKey を取得していること。詳細については、「ARTC アプリケーションの作成」をご参照ください。
サンプルコード
サーバー側での生成 (推奨)
Alibaba Cloud は、Go、Java、Python などの言語向けのコード例を提供しています。「トークン生成コード例」をご参照ください。
クライアント側での生成 (開発およびデバッグのみ)
トークンの生成には AppKey が必要なため、クライアント側のコードに AppKey を埋め込むと重大なセキュリティリスクとなります。本番環境のアプリケーションでは、アプリサーバー上でトークンを生成し、クライアントに配布してください。
開発およびデバッグ中に、アプリサーバーがまだトークンを生成していない場合は、APIExample のロジックを参照して、クライアント上で一時的にトークンを生成できます。サンプルコード:
Android クライアントでのトークン生成: Android/ARTCExample/KeyCenter/src/main/java/com/aliyun/artc/api/keycenter/ARTCTokenHelper.java
iOS クライアントでのトークン生成: iOS/ARTCExample/Common/ARTCTokenHelper.swift
トークンによるチャネル参加
本番環境のアプリケーションでは、セキュリティを確保するため、アプリサーバー上でトークンを生成し、クライアントに配布することを強く推奨します。
Android クライアントでのトークンを使用したチャネル参加: Android/ARTCExample/QuickStart/src/main/java/com/aliyun/artc/api/quickstart/TokenGenerate/TokenGenerateActivity.java
iOS クライアントでのトークンを使用したチャネル参加: iOS/ARTCExample/QuickStart/TokenGenerate/TokenGenerateVC.swift
仕組み
トークンワークフロー
-
クライアントがアプリサーバーにトークンをリクエストします。アプリサーバーは、必要なルールに基づいてトークンを生成し、返却します。
-
クライアントは、トークン、AppID、チャネル ID、ユーザー ID、およびその他の情報を使用して、指定されたチャネルに参加します。
-
Alibaba Cloud ARTC サービスがトークンを検証し、クライアントのチャネルへの参加を許可します。
トークン生成
次の表は、トークンの生成に使用されるパラメーターを示しています。
|
パラメーター |
説明 |
|
AppID |
ARTC アプリケーションの ID とキー。ApsaraVideo Live コンソールで ARTC アプリケーションを作成する際に生成されます。「アプリケーション開発パラメーターの取得」をご参照ください。 |
|
AppKey |
|
|
ChannelId |
ユーザー定義のチャネル ID。値は 文字列 である必要があり、long 型は使用できません。数字、大文字、小文字、ハイフン (-)、およびアンダースコア (_) を含めることができ、長さは 64 文字を超えることはできません。ホストと Co-ストリーミング ゲストは、同じチャネル ID を使用する必要があります。 |
|
UserID |
ユーザー定義のユーザー ID。値は 文字列 である必要があり、long 型は使用できません。数字、大文字、小文字、ハイフン (-)、およびアンダースコア (_) を含めることができ、長さは 64 文字を超えることはできません。 |
|
nonce |
ノンスは空の文字列にすることができます。空のままにすることを 推奨します。 |
|
timestamp |
有効期限のタイムスタンプ (秒単位)。有効期限を 24 時間に設定することを推奨します。24 時間の有効期限を設定するには、現在のタイムスタンプ (秒単位) に 86,400 (24 * 60 * 60) を加算します。 |
トークン生成プロセスの例:

トークン生成コード例:
// 1. フィールドを連結: AppID+AppKey+ChannelId+UserID+timestamp
// 2. SHA-256 アルゴリズムを使用して連結された文字列をハッシュし、トークンを生成します。
token = sha256(AppID+AppKey+ChannelId+UserID+timestamp)
// 例:
AppID = "abc", AppKey = "abckey", ChannelId = "abcChannel", UserID = "abcUser", timestamp = 1699423634
token = sha256("abcabckeyabcChannelabcUser1699423634") = "3c9ee8d9f8734f0b7560ed8022a0590659113955819724fc9345ab8eedf84f31"
ARTC シナリオ
以下の例は、Android および iOS の ARTC シナリオにおいて、トークンを使用してチャネルに参加するユーザーを認証する方法を示しています。
単一パラメーター方式 (推奨)
ARTC SDK は、チャネル参加用の単一パラメーター API を提供しています。この方式により、アプリサーバーとクライアント間のパラメーターの不整合によるチャネル参加の失敗を防ぐことができます。認証 token、appid、channelid、nonce、userid、および timestamp を JSON オブジェクトにパッケージ化し、JSON 文字列を Base64 エンコードして、新しい認証文字列 (Base64 トークン) を作成します。
Alibaba Cloud のテクニカルサポートに連絡する際は、Base64 トークンまたは設定したユーザー名を提供する必要があります。

Base64 トークン生成の例
Java
package com.example;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.Calendar;
import org.json.JSONObject;
public class App {
public static String createBase64Token(String appid, String appkey, String channelid, String userid) {
// 有効期限のタイムスタンプを計算 (現在から 24 時間後)
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.HOUR_OF_DAY, 24);
long timestamp = calendar.getTimeInMillis() / 1000;
// 文字列を連結
String stringBuilder = appid + appkey + channelid + userid + timestamp;
// SHA-256 ハッシュを計算
String token = sha256(stringBuilder);
// JSON オブジェクトを作成
JSONObject base64tokenJson = new JSONObject();
base64tokenJson.put("appid", appid);
base64tokenJson.put("channelid", channelid);
base64tokenJson.put("userid", userid);
base64tokenJson.put("nonce", "");
base64tokenJson.put("timestamp", timestamp);
base64tokenJson.put("token", token);
// JSON オブジェクトを文字列に変換し、Base64 でエンコード
String jsonStr = base64tokenJson.toString();
String base64token = Base64.getEncoder().encodeToString(jsonStr.getBytes(StandardCharsets.UTF_8));
return base64token;
}
private static String sha256(String input) {
try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest(input.getBytes(StandardCharsets.UTF_8));
StringBuilder hexString = new StringBuilder();
for (byte b : hash) {
String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1)
hexString.append('0');
hexString.append(hex);
}
return hexString.toString();
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) {
String appid = "your_appid";
String appkey = "your_appkey";
String channel_id = "your_channel_id";
String user_id = "your_user_id";
String base64token = createBase64Token(appid, appkey, channel_id, user_id);
System.out.println("Base64 Token: " + base64token);
}
}
Go
package main
import (
"crypto/sha256"
"encoding/base64"
"encoding/hex"
"encoding/json"
"fmt"
"time"
)
func createBase64Token(appid, appkey, channelID, userID string) (string, error) {
// 有効期限のタイムスタンプを計算 (現在から 24 時間後)
timestamp := time.Now().Add(24 * time.Hour).Unix()
// 文字列を連結
stringBuilder := appid + appkey + channelID + userID + fmt.Sprintf("%d", timestamp)
// SHA-256 ハッシュを計算
hasher := sha256.New()
hasher.Write([]byte(stringBuilder))
token := hasher.Sum(nil)
// encoding/hex を使用してハッシュを 16 進数文字列に変換
tokenHex := hex.EncodeToString(token)
// JSON オブジェクトを作成
tokenJSON := map[string]interface{}{
"appid": appid,
"channelid": channelID,
"userid": userID,
"nonce": "",
"timestamp": timestamp,
"token": tokenHex,
}
// JSON オブジェクトを文字列に変換し、Base64 でエンコード
jsonBytes, err := json.Marshal(tokenJSON)
if err != nil {
return "", err
}
base64Token := base64.StdEncoding.EncodeToString(jsonBytes)
return base64Token, nil
}
func main() {
appid := "your_appid"
appkey := "your_appkey"
channelID := "your_channel_id"
userID := "your_user_id"
token, err := createBase64Token(appid, appkey, channelID, userID)
if err != nil {
fmt.Println("Error creating token:", err)
return
}
fmt.Println("Base64 Token:", token)
}
Python
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
import hashlib
import datetime
import time
import base64
import json
def create_base64_token(app_id, app_key, channel_id, user_id):
expire = datetime.datetime.now() + datetime.timedelta(days=1)
timestamp = int(time.mktime(expire.timetuple()))
h = hashlib.sha256()
h.update(str(app_id).encode('utf-8'))
h.update(str(app_key).encode('utf-8'))
h.update(str(channel_id).encode('utf-8'))
h.update(str(user_id).encode('utf-8'))
h.update(str(timestamp).encode('utf-8'))
token = h.hexdigest()
jsonToken = {'appid':app_id,
'channelid':channel_id,
'userid':user_id,
'nonce':'',
'timestamp':timestamp,
'token':token
}
base64Token = base64.b64encode(json.dumps(jsonToken).encode())
return base64Token
def main():
app_id = 'your_appid'
app_key = 'your_appkey'
channel_id = 'your_channel_id'
user_id = 'your_user_id'
base64Token = create_base64_token(app_id, app_key, channel_id, user_id)
print(base64Token)
if __name__ == '__main__':
main()
Node.js
'use strict'
const crypto = require('crypto')
function create_base64_token(appid, appkey, channelid, userid) {
let timestamp = Math.floor(Date.now() / 1000 + 24 * 60 * 60)
let string_builder = appid + appkey + channelid + userid + timestamp.toString()
let token = crypto.createHash('sha256').update(string_builder).digest('hex')
let base64tokenJson = {
appid:appid,
channelid:channelid,
userid:userid,
nonce:'',
timestamp:timestamp,
token:token
}
let base64token = Buffer.from(JSON.stringify(base64tokenJson), 'utf-8').toString('base64')
return base64token
}
let appid = "your_appid";
let appkey = "your_appkey";
let channel_id = "your_channel_id";
let user_id = "your_user_id";
let base64token = create_base64_token(appid, appkey, channel_id, user_id)
console.log(base64token)
Rust
use chrono::{Duration, Utc};
use sha2::{Sha256, Digest};
use serde_json::json;
use base64::encode;
fn create_base64_token(appid: &str, appkey: &str, channel_id: &str, user_id: &str) -> String {
// 有効期限のタイムスタンプを計算 (現在から 24 時間後)
let timestamp = (Utc::now() + Duration::hours(24)).timestamp();
// 文字列を連結
let string_builder = format!("{}{}{}{}{}", appid, appkey, channel_id, user_id, timestamp);
// SHA-256 ハッシュを計算
let mut hasher = Sha256::new();
hasher.update(string_builder);
let token = hasher.finalize();
let token_hex = format!("{:x}", token);
// JSON オブジェクトを作成
let token_json = json!({
"appid": appid,
"channelid": channel_id,
"userid": user_id,
"nonce": "",
"timestamp": timestamp,
"token": token_hex
});
// JSON オブジェクトを文字列に変換し、Base64 でエンコード
let base64_token = encode(token_json.to_string());
base64_token
}
fn main() {
let appid = "your_appid";
let appkey = "your_appkey";
let channel_id = "your_channel_id";
let user_id = "your_user_id";
let token = create_base64_token(appid, appkey, channel_id, user_id);
println!("Base64 Token: {}", token);
}
クライアント API 呼び出しの例
クライアントはアプリサーバーから取得した Base64 トークン を使用してチャンネルに参加します。
-
Android:
// channelId と userId は null に設定できます。channelId と userId に値を渡す場合は、トークンの生成に使用した値と一致する必要があります。この機能を使用して、サーバーとクライアント間のパラメーターの整合性を検証できます。 // base64Token は Base64 エンコードされたトークンです。 // username はトラブルシューティングのために渡す識別子です。 mAliRtcEngine.joinChannel(base64Token, null, null, "username"); -
iOS:
// channelId と userId は null に設定できます。channelId と userId に値を渡す場合は、トークンの生成に使用した値と一致する必要があります。この機能を使用して、サーバーとクライアント間のパラメーターの整合性を検証できます。 // base64Token は Base64 エンコードされたトークンです。 // username はトラブルシューティングのために渡す識別子です。 [self.engine joinChannel:base64Token channelId:nil userId:nil name:@"username" onResultWithUserId:nil];
複数パラメーター方式
ARTC SDK は、チャネル参加用の複数パラメーター API も提供しています。この方式では、AliRtcAuthInfo データ構造を使用して、認証用のトークンとユーザー情報を格納します。
チャネル参加に使用するチャネル ID とユーザー ID は、トークンの生成に使用したものと一致する必要があります。
-
Android:
// 複数パラメーター方式用のトークンとユーザー情報を設定します。 AliRtcAuthInfo authInfo = new AliRtcAuthInfo(); authInfo.appId = appId; authInfo.channelId = channelId; authInfo.userId = userId; authInfo.timestamp = timestamp; authInfo.nonce = nonce; authInfo.token = token; // チャネルに参加します。 mAliRtcEngine.joinChannel(authInfo, ""); -
iOS:
// 複数パラメーター方式用のトークンとユーザー情報を設定します。 let authInfo = AliRtcAuthInfo() authInfo.appId = appId authInfo.channelId = channelId authInfo.nonce = nonce authInfo.userId = userId authInfo.timestamp = timestamp authInfo.token = authToken // チャネルに参加します。 self.rtcEngine?.joinChannel(authInfo, name: nil)
Co-ストリーミング シナリオ
共同ストリーミング URL の query 文字列に、token、AppID、ChannelID、nonce、userId、timestamp パラメーターを追加し、その URL を SDK に渡します。 URL フィールドの詳細については、「共同ストリーミング URL のルール」をご参照ください。
URL の例
Co-ストリーミングまたはバトル シナリオのインジェスト URL:
artc://live.aliyun.com/push/633?timestamp=1685094092&token=fe4e674ade****6686&userId=718&sdkAppId=xxx
Co-ストリーミングまたはバトル シナリオのストリーミング URL:
artc://live.aliyun.com/play/633?timestamp=1685094092&token=fe4e674ade****6686&userId=718&sdkAppId=xxx
live.aliyun.com は Co-ストリーミング URL の固定プレフィックスであり、実際のドメイン名ではありません。ping、traceroute、telnet などのドメイン関連の操作を実行しないでください。
トークンの有効期限の処理
トークンを作成する際、timestamp フィールドで有効期限を定義します。
ユーザーがトークンを使用してチャネルに参加した後:
-
SDK は、トークンの有効期限が切れる 30 秒前に
onAuthInfoWillExpireコールバックをトリガーします。refreshAuthInfoメソッドを呼び出して、認証情報を更新できます。 -
トークンの有効期限が切れると、SDK は
onAuthInfoExpiredコールバックをトリガーします。チャネルに留まるには、ユーザーはチャネルに再参加する必要があります。