日本時間5月16日のContent Cloud Summitで、カスタムアプリにBox AI APIを活用する方法を紹介します。

詳細を表示

注釈トークン

注釈トークン

注釈は、新しいBox Viewでサポートされる主な機能の1つです。開発者はこの機能を使用して、アプリケーションに埋め込まれたプレビュー内から直接、コラボレーション機能を提供できます。

Box Viewでは、ハイライトのみ、ハイライト注釈、およびポイント注釈という3つの注釈の種類をサポートしています。注釈はドキュメントと画像のプレビューのみでサポートされます。

注釈トークンのしくみ

注釈トークンとは

注釈トークンとは、ユーザーが注釈を付けることができるファイルに対してアプリケーションがプレビューの埋め込みリンクを作成できるようにするアクセストークンです。アプリケーションでは、アプリケーションのユーザーそれぞれに新しいApp Userが作成されない可能性があるため、注釈トークンを使用すると、注釈を付けたユーザーを追跡できます。

注釈トークンは、一意のユーザーIDと表示名にリンクされているプレビューセッション (有効期限付き埋め込みリンク) を生成するために、通常のアクセストークン、アプリトークン、またはファイルトークンの代わりに使用されます。

注釈トークンを使用して生成されたプレビューセッションは特定の外部ユーザーに関連付けられるため、アプリケーションでは、アプリケーションのエンドユーザーごとに異なる注釈トークンを使用して、個別にプレビューセッションを生成することを強くお勧めします。

外部ユーザー情報

注釈に関連付けられた外部の表示名は、実際のところ、注釈に追加されるステートレスな「ラベル」です。つまり、注釈が追加されると、その表示名は完全に注釈と関連付けられるため、注釈を削除し、更新した表示名を使用して再度追加しなければ更新できません。

SDKを使用せずに作成

注釈トークンを作成するには、JWTを使用して手動で認証する手順に従いますが、その際、JWTクレームを次のデータに置き換えます。

.Net
var claims = new List<Claim>{
  new Claim("sub", '[EXTERNAL_USER_ID]'),
  new Claim("name", '[EXTERNAL_USER_DISPLAY_NAME]'),
  new Claim("box_sub_type", "external"),
  new Claim("jti", jti),
};
Java
JwtClaims claims = new JwtClaims();
claims.setIssuer(config.boxAppSettings.clientID);
claims.setAudience(authenticationUrl);
claims.setSubject("[EXTERNAL_USER_ID]");
claims.setName("[EXTERNAL_USER_DISPLAY_NAME]");
claims.setClaim("box_sub_type", "external");
claims.setGeneratedJwtId(64);
claims.setExpirationTimeMinutesInTheFuture(0.75f);
Python
claims = {
  'iss': config['boxAppSettings']['clientID'],
  'sub': '[EXTERNAL_USER_ID]',
  'name': '[EXTERNAL_USER_DISPLAY_NAME]',
  'box_sub_type': 'external',
  'aud': authentication_url,
  'jti': secrets.token_hex(64),
  'exp': round(time.time()) + 45
}
Node
let claims = {
  iss: config.boxAppSettings.clientID,
  sub: "[EXTERNAL_USER_ID]",
  name: "[EXTERNAL_USER_DISPLAY_NAME]",
  box_sub_type: "external",
  aud: authenticationUrl,
  jti: crypto.randomBytes(64).toString("hex"),
  exp: Math.floor(Date.now() / 1000) + 45
};
Ruby
claims = {
  iss: config['boxAppSettings']['clientID'],
  sub: "[EXTERNAL_USER_ID]",
  name: "[EXTERNAL_USER_DISPLAY_NAME]",
  box_sub_type: 'external',
  aud: authentication_url,
  jti: SecureRandom.hex(64),
  exp: Time.now.to_i + 45
}
PHP
$claims = [
  'iss' => $config->boxAppSettings->clientID,
  'sub' => '[EXTERNAL_USER_ID]',
  'name' => '[EXTERNAL_USER_DISPLAY_NAME]',
  'box_sub_type' => 'external',
  'aud' => $authenticationUrl,
  'jti' => base64_encode(random_bytes(64)),
  'exp' => time() + 45,
  'kid' => $config->boxAppSettings->appAuth->publicKeyID
];
パラメータ説明
subStringこの注釈を関連付ける外部ユーザーID。このIDには、アプリケーションで追跡される任意のIDを使用できます。
box_sub_typeString外部ユーザーIDを示す場合はexternal
box_sub_typeStringこの注釈を関連付ける外部ユーザー名。これはBox UIに表示されます。

その後、ガイドに従ってこのクレームをアサーションに変換し、このアサーションを、既存の有効なアクセストークン、アプリトークン、またはファイルトークンのほか、スコープのセット、トークンの作成対象となるリソースとともにPOST /oauth2/tokenエンドポイントに渡します。

.Net
var content = new FormUrlEncodedContent(new[]
{
  new KeyValuePair<string, string>(
    "grant_type", "urn:ietf:params:oauth:grant-type:token-exchange"),
  new KeyValuePair<string, string>(
    "resource", "https://api.box.com/2.0/files/123456"),
  new KeyValuePair<string, string>(
    "subject_token", "[ACCESS_TOKEN]"),
  new KeyValuePair<string, string>(
    "subject_token_type", "urn:ietf:params:oauth:token-type:access_token"),
  new KeyValuePair<string, string>(
    "scope", "item_preview"),
  new KeyValuePair<string, string>(
    "actor_token", "[JWT_ASSERTION_FOR_ANNOTATOR_TOKEN]"),
  new KeyValuePair<string, string>(
    "actor_token_type", "urn:ietf:params:oauth:token-type:id_token"),
});
Java
List<NameValuePair> params = new ArrayList<NameValuePair>();

params.add(new BasicNameValuePair(
  "grant_type", "urn:ietf:params:oauth:grant-type:token-exchange"));
params.add(new BasicNameValuePair(
  "resource", "https://api.box.com/2.0/files/123456"));
params.add(new BasicNameValuePair(
  "subject_token", "[ACCESS_TOKEN]"));
params.add(new BasicNameValuePair(
  "subject_token_type", "urn:ietf:params:oauth:token-type:access_token"));
params.add(new BasicNameValuePair(
  "scope", "item_preview"));
params.add(new BasicNameValuePair(
  "actor_token", "[JWT_ASSERTION_FOR_ANNOTATOR_TOKEN]"));
params.add(new BasicNameValuePair(
  "actor_token_type", "urn:ietf:params:oauth:token-type:id_token"));
Python
params = urlencode({
  'grant_type': 'urn:ietf:params:oauth:grant-type:token-exchange',
  'resource': 'https://api.box.com/2.0/files/123456',
  'subject_token': '[ACCESS_TOKEN]',
  'subject_token_type': 'urn:ietf:params:oauth:token-type:access_token',
  'scope': 'item_preview',
  'actor_token': '[JWT_ASSERTION_FOR_ANNOTATOR_TOKEN]',
  'actor_token_type': 'urn:ietf:params:oauth:token-type:id_token'
}).encode()
Node
let accessToken = await axios
  .post(
    authenticationUrl,
    querystring.stringify({
      grant_type: "urn:ietf:params:oauth:grant-type:token-exchange",
      resource: "https://api.box.com/2.0/files/123456",
      subject_token: "[ACCESS_TOKEN]",
      subject_token_type: "urn:ietf:params:oauth:token-type:access_token",
      scope: "item_preview",
      actor_token: "[JWT_ASSERTION_FOR_ANNOTATOR_TOKEN]",
      actor_token_type: "urn:ietf:params:oauth:token-type:id_token"
    })
  )
  .then(response => response.data.access_token);
Ruby
params = URI.encode_www_form({
  grant_type: 'urn:ietf:params:oauth:grant-type:token-exchange',
  resource: 'https://api.box.com/2.0/files/123456',
  subject_token: '[ACCESS_TOKEN]',
  subject_token_type: 'urn:ietf:params:oauth:token-type:access_token',
  scope: 'item_preview',
  actor_token: '[JWT_ASSERTION_FOR_ANNOTATOR_TOKEN]',
  actor_token_type: 'urn:ietf:params:oauth:token-type:id_token'
})
PHP
$params = [
  'grant_type' => 'urn:ietf:params:oauth:grant-type:token-exchange',
  'resource' => 'https://api.box.com/2.0/files/123456',
  'subject_token' => '[ACCESS_TOKEN]',
  'subject_token_type' => 'urn:ietf:params:oauth:token-type:access_token',
  'scope' => 'item_preview',
  'actor_token' => '[JWT_ASSERTION_FOR_ANNOTATOR_TOKEN]',
  'actor_token_type' => 'urn:ietf:params:oauth:token-type:id_token'
];
パラメータ説明
resourceトークンが制限されるファイルへの完全なURLパス (省略可)。
actor_token以前に作成されたJWTアサーション
actor_token_type常にurn:ietf:params:oauth:token-type:id_tokenに設定します。

SDKを使用して作成

SDKを使用してJWT注釈トークンを作成するために、アプリケーションはアクティブなトークンを別のトークンと交換できます。

Node
var options = {
  actor: {
    id: "[EXTERNAL_USER_ID]",
    name: "[EXTERNAL_USER_DISPLAY_NAME"
  }
};

client
  .exchangeToken(
    "item_preview",
    "https://api.box.com/2.0/files/123456",
    options
  )
  .then(tokenInfo => {
    //=> tokenInfo.accessToken
  });