アクセス権限を設定してAlexaへのユーザー認証を実現する



アクセス権限を設定してAlexaへのユーザー認証を実現する

ディレクティブに対して非同期で応答するとき、または変更レポートをAlexaのイベントゲートウェイに送信するときに、システムのユーザーをAlexaで認証する必要があります。そのためには、認証情報をイベントメッセージのscopeに提供します。このドキュメントは、メッセージをAlexaに送信する際にユーザーの認証情報を取得して提供するプロセスについて説明しています。

認可を取得する

Alexaイベントゲートウェイにメッセージを送信する権限を持つスキルをユーザーが最初に有効にするとき、または以前に有効にしたスキルがv2からv3に移行されるときに、AlexaはAcceptGrantディレクティブと呼ばれるメッセージをユーザーごとに送信します。AcceptGrantには、システム内のユーザーを特定するベアラートークンと認可コードが含まれます。これによって、Alexaを使用するそのユーザーの資格情報を取得できます。提供された認可コードを使用すると、Login with Amazon(LWA)を呼び出して、アクセストークンと更新トークンを取得することができます。

以下の図は、ユーザーを認証し、ユーザーの代わりにメッセージを送信するプロセスを示しています。

ユーザーの代わりに非同期応答またはデバイス状態の変更レポートを送信するたびに、イベントゲートウェイに対するメッセージのscopeの中にアクセストークンを組み込みます。メッセージの構造は同期応答の場合と同じですが、メッセージの送信先はイベントゲートウェイです。

注: 認証トークンを格納および送信する際には、いつでもOAuth 2のベストプラクティスに従ってください。つまり、トークンやその他の識別情報は、セキュアな方法で格納および交換する必要があります。

このプロセスには、次の2つの重要な注意事項があります。

  1. 認可コードには有効期限(数分)があるため、アクセストークンと更新トークンの認可コードは直ちに交換する必要があります。認可コードの有効期限が切れると、ユーザーはスキルを無効にしてもう一度有効にする必要があります。これにより、認可コードが生成され、AcceptGrantディレクティブによってLambda関数に送信されます。

  2. ユーザーのアクセストークンと更新トークンは保管しておく必要があり、非同期イベントまたは変更レポートイベントにはそれぞれアクセストークンを含める必要があります。これらのトークンの有効期限が切れる前に、格納しておいた更新トークンを使用して新しいアクセストークンと更新トークンを取得してください。なお、LWAガイドラインによると、アクセストークンの有効期限は60分です。

また、スキルがv2からv3に移行されるときにイベントをAlexaイベントゲートウェイに送信する権限をリクエストしていた場合、バックフィルプロセスが発生し、スキルを有効にしたユーザーごとにAcceptGrantディレクティブを受け取ります。これらのメッセージを受け取る準備をし、認証プロセスを完了してください。

非同期メッセージ認証のステップ

  1. 開発者コンソールにサインインし、スキルを選択します。
  2. アクセス権限ページで、Alexaイベントを送るをスライドさせてスキルが非同期応答と変更レポートイベントを送信することを示します。
  3. 保存をクリックします。
  4. Alexaスキルメッセージングが表示されます。このセクションのクライアントIDクライアントシークレットをメモしてください。ユーザーのアクセストークンをリクエストするためにこれらの値が必要になります。アクセス権限スライダーと、クライアントIDおよびクライアントシークレットの例を次の図に示します。
    スマートホームのアクセス権限


  5. AcceptGrantディレクティブを処理するコードをLambda関数に追加します。このディレクティブは、ユーザーがスキルを有効化するたびに受け取ることになります。AcceptGrantメッセージの例を次に示します。AcceptGrantメッセージの詳細については、Alexa.Authorizationインターフェースを参照してください。AcceptGrantメッセージをスキルに送信される前に、スキルが有効化され、システム内のアカウントにアカウントリンクされている必要があります。詳細については、スキルをテストするを参照してください
{
  "directive": {
    "header": {
      "namespace": "Alexa.Authorization",
      "name": "AcceptGrant",
      "messageId": "5f8a426e-01e4-4cc9-8b79-65f8bd0fd8a4",
      "payloadVersion": "3"
    },
    "payload": {
      "grant": {
        "type": "OAuth2.AuthorizationCode",
        "code": "VGhpcyBpcyBhbiBhdXRob3JpemF0aW9uIGNvZGUuIDotKQ=="
      },
      "grantee": {
        "type": "BearerToken",
        "token": "bearer-token-representing-user"
      }
    }
  }
}
  • 受信したAcceptGrantディレクティブごとにAcceptGrant.Responseを返します。エラーが発生した場合は、ACCEPT_GRANT_FAILEDエラー応答を返してください。

スキルのテストを有効にする

認証メッセージフローを開始するには:

  1. 開発者コンソールのテストページで、テストするスキルを有効にします。
  2. Alexaアプリでスキルを有効にし、スキルにアカウントをリンクします。リンクが成功すると、有効な認可コードと一緒にAcceptGrantディレクティブが送信されます。
  3. AcceptGrantディレクティブのcodeフィールドの値を使用して、LWAにアクセストークンリクエストを送信し、アクセストークンを取得します。セキュアなHTTP POSTを、次の表に記載されているパラメーターと一緒にhttps://api.amazon.com/auth/o2/tokenに送信します。詳細については、LWAドキュメントのアクセストークンリクエストに関するトピックを参照してください。
パラメーター 説明
grant_type 必須。付与をリクエストされたアクセスの種類です。authorization_codeである必要があります。
code 必須。AcceptGrantディレクティブのcodeで与えられた値です。
client_id 必須。クライアントの識別子です。開発者コンソールのアクセス権限セクションで与えられた値です。
client_secret 必須。クライアントシークレットです。開発者コンソールのアクセス権限セクションで与えられた値です。

redirect_uriが必須かどうかに関してLWAドキュメントでは明示されていませんが、必須ではなく、リクエストに組み込むべきではありません。

例:

 POST /auth/o2/token HTTP/l.l
 Host: api.amazon.com
 Content-Type: application/x-www-form-urlencoded;charset=UTF-8
 grant_type=authorization_code&code=SplxlOBezQQYbYS6WxSbIA&client_id=smarthome&client_secret=Y76SDl2F
  • 戻ってきたベアラートークンと更新トークンを格納します。これらのトークンは、AcceptGrantメッセージのGranteeセクションで識別されるユーザーといつでも関連付けることができる必要があります。応答の例を次に示します。
 HTTP/l.l 200 OK
 Content-Type: application/json;charset UTF-8
 Cache-Control: no-store
 Pragma: no-cache
 {
    "access_token":"Atza|IQEBLjAsAhRmHjNgHpi0U-Dme37rR6CuUpSR...",
    "token_type":"bearer",
    "expires_in":3600,
    "refresh_token":"Atzr|IQEBLzAtAhRPpMJxdwVz2Nn6f2y-tpJX2DeX..."
 }
  • Alexaイベントゲートウェイに対するメッセージのscopeでaccess_tokenの値を使用します。エンドポイントは、次のとおりです。

  • 北米:https://api.amazonalexa.com/v3/events
  • ヨーロッパ:https://api.eu.amazonalexa.com/v3/events
  • 極東:https://api.fe.amazonalexa.com/v3/events

メッセージのscopeでHTTP Authorizationヘッダーおよびベアラートークンとして指定された認可トークンを含むサンプルメッセージ:


POST api-amazonalexa.com
Authorization: Bearer Atza|IQEBLjAsAhRmHjNgHpi0U-Dme37rR6CuUpSR...
Content-Type: application/json

{
  "context": {
    "properties": [ {
      "namespace": "Alexa.LockController",
      "name": "lockState",
      "value": "LOCKED",
      "timeOfSample": "2017-02-03T16:20:50.52Z",
      "uncertaintyInMilliseconds": 1000
    } ]
  },
  "event": {
    "header": {
      "namespace": "Alexa",
      "name": "Response",
      "payloadVersion": "3",
      "messageId": "5f8a426e-01e4-4cc9-8b79-65f8bd0fd8a4",
      "correlationToken": "dFMb0z+PgpgdDmluhJ1LddFvSqZ/jCc8ptlAKulUj90jSqg=="
    },
    "endpoint": {
      "scope": {
        "type": "BearerToken",
        "token": "Atza|IQEBLjAsAhRmHjNgHpi0U-Dme37rR6CuUpSR..."
      },
      "endpointId": "appliance-001"
    },
    "payload": {}
  }
}

新しい認可コードをリクエストする

ユーザーに関連付けられていたアクセストークンや更新トークンを失った場合は、バックフィルプロセスを使って新しいトークンをリクエストする必要があります。開発者サポートページのお問い合わせフォームを使用して、プロセスを開始してください。このフォームを送信すると、リストに追加され、スキルを有効にしたユーザーごとにAcceptGrantディレクティブが再送されます。

その際、次の情報をお知らせください。

  • Eメールアドレス: スキルに関連付けられている開発者アカウントのEメールアドレスを指定してください。
  • カテゴリー: Alexa
  • お問い合わせ内容: スキルの認証バックフィルをリクエストし、スキルIDを提供します。

バックフィルリクエストは1週間に1回処理されるため、スキルを有効にしたユーザーごとの認可コードを受け取る準備をしておく必要があります。1秒間に受け取るトランザクションの数は最大で10個です。その数のメッセージを処理できない場合は、リクエストの際にお知らせください。

バックフィルが完了するまでAlexaイベントゲートウェイに送信される応答はすべて失敗します。完了までの間は同期イベントのみを送ることができます。

有効期限が切れたトークンの通知および更新トークンの使用

有効期限が切れたトークンでAlexaイベントゲートウェイにメッセージを送信すると、HTTP 401 Unauthorized応答を受け取ります。詳細については、ゲートウェイからのエラー応答を参照してください。ベストプラクティスとして、アクセストークンの有効期限が切れる前に、更新トークンを使用して新しいアクセストークンと更新トークンをLWAにリクエストしてください。LWAガイドラインによると、トークンの有効期限は1時間です。更新トークンの使用方法の詳細については、更新トークンの使用に関するLWAのドキュメントを参照してください。

認可を取り消す

Alexaが認可グラントを取り消す理由には、次のものがあります。

  • ユーザーによってスキルが無効にされた。
  • ユーザーがAmazonアカウントのアカウント>Login with Amazonの管理ページにアクセスしてスキルの同意を明示的に取り消した。

取り消されたGrantの通知

認可Grantが取り消されたという通知を受け取るのは、主に次の2つの場合です。

  • 有効期限が切れていないトークンでイベントを送信したときにHTTP 403を受け取る場合。 これは、スキルが無効にされたか、ユーザーが同意を取り消したものの、取得したトークンの有効期限が切れていない場合に発生します。

403の応答の例

HTTP/1.1 403 Forbidden
Date: Wed, 07 Mar 2018 20:25:31 GMT
Connection: close

{
  "header": {
    "namespace": "System",
    "name": "Exception",
    "messageId": "90c3fc62-4b2d-460c-9c8b-77251f1698a0"
  },
  "payload": {
    "code": "SKILL_DISABLED_EXCEPTION",
    "description": "スキルが無効にされました。そのユーザーに関するイベントの送信を停止するには、3Pがそのスキルがユーザーによって無効にされたことを明確に識別する必要があります”
  }
}

  • トークンを更新できない場合。 この状況でトークンの更新を試みると、invalid_grantエラーコードをLWAから受け取ります。これは永続的な状態であり、ユーザーによって認可が取り消されたことを示しています。詳細については、LWAドキュメントのアクセストークンエラーに関するトピックを参照してください。

ユーザーが同意を取り消すと、認可Grantが取り消され、ユーザーのアカウントに関連付けられた一部またはすべてのリソースへのスキルによるアクセスも拒否されます。Grantに依存するイベントの送信を停止するために、スキル内のロジックとサポートシステムがなければなりません。たとえば、イベントゲートウェイへの非同期メッセージなどです。機能の他の部分は通常どおり機能する必要があります。