AppStream2.0 ストリーミングURLにアクセスするとエラーになる→User IDが原因かも?
AppStream 2.0 Stackから「Create Streaming URL」をクリックして、いよいよアプリケーションのストリーミングだ!生成されたURLにアクセスしてストリーミング開始するぞ!
試してみてほしいこと
「Create Streaming URL」時にUser IDを指定しますが、これをシンプルな文字列、例えば「hoge」などにしてみてエラーが起きるか試してみてください。 これでストリーミングが成功したのであれば、最初の500エラーはUser IDの値に拠るものと思われます。
User IDには最大文字数と使用可能文字種の仕様がある
前述の「Create Streaming URL」処理の裏で実行されているAPIは以下のCreateStreamingURL
です。
こちらの Request Syntax
欄に以下記載があります。
UserId The identifier of the user. Type: String Length Constraints: Minimum length of 2. Maximum length of 32. Pattern: [\w+=,.@-]* Required: Yes
- 文字数については、2文字以上32文字以下
- 文字種については、
[\w+=,.@-]*
つまり以下の文字種から構成される必要がある- アルファベット(大文字小文字どちらも)
- 数字
- アンダースコア(
_
) - プラス(
+
) - イコール(
=
) - カンマ(
,
) - ピリオド(
.
) - アットマーク(
@
) - ハイフン(
-
)
このいずれかに抵触して500エラーになったのだと思います。
エラーになるのはURLを生成した際(CreateStreamingURL
API実行時)ではなく、生成されたURLにアクセスした際です。
この仕様を守れない場合の解決案
私がこの仕様に出くわしたのは、以下の「Amazon AppStream 2.0 を使用して SaaS ポータルを作成する」Getting Startedをやっていた際です。
このガイドでは、Cognito User Poolのユーザーのメールアドレスを、AppStreamのUser IDに指定してストリーミングURLを生成しています。
// API GatewayのCognitoオーソライザーからusernameを取得(usernameがメールアドレスになっています) const username = event.requestContext.authorizer.claims['cognito:username']; // // 省略 // // パラメータを作成 // UserIdに先程のusernameを代入 var params = { FleetName: '<Fleet-Name>', /* required */ StackName: '<Stack-Name>', /* required */ UserId: username, Validity: 5 }; // // 省略 // // そのパラメーターをAppStreamのcreateStreamingURLに渡す var request = appstream.createStreamingURL(params);
※ ここのステップ3の中に全体のコードがあります
一意なユーザーの情報としてメールアドレスを使うのは一般的だと思います。が、メールアドレス文字数が32文字以下であるという保障は無いですよね。どうすればメールアドレスをUser ID値として使いつつ前述のエラーを回避できるでしょうか。
例えば、メールアドレスをハッシュ化してみてはどうでしょう。md5でハッシュ化すると(元が33文字以上の文字列でも)32文字の一意な文字列になります。これをUser IDに使います。
+ const crypto = require("crypto"); // API GatewayのCognitoオーソライザーからusernameを取得(usernameがメールアドレスになっています) const username = event.requestContext.authorizer.claims['cognito:username']; + // ハッシュ化 + const hashedUsername = crypto + .createHash("md5") + .update(username) + .digest("hex"); // // 省略 // // パラメータを作成 - // UserIdに先程のusernameを代入 + // UserIdに先程のhashedUsernameを代入 var params = { FleetName: '<Fleet-Name>', /* required */ StackName: '<Stack-Name>', /* required */ - UserId: username, + UserId: hashedUsername, Validity: 5 }; // // 省略 // // そのパラメーターをAppStreamのcreateStreamingURLに渡す var request = appstream.createStreamingURL(params);
このコードに修正して先程のエラーになったユーザーで再度試してみると… 無事ストリーミングURLへのアクセスが成功しました!