この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
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へのアクセスが成功しました!