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



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

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

認可を取得する

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

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

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

認証トークンを安全な方法で格納して送信するため、OAuth 2.0のベストプラクティスに従ってください。スキルは、トークンとその他の識別情報を次のように処理する必要があります。

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

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

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

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

非同期メッセージ認証をスキルに追加するには、以下の手順を実施します。

Alexaイベントの権限を有効にする

スキルで非同期の応答や変更レポートイベントを送信するよう指定するには、以下の手順を実施します。

Alexaイベントを送信する権限を有効にする

  1. Alexa開発者コンソールにログインし、スキルを選択します。
  2. スキルの一覧からスマートホームスキルを見つけ、アクションを選択のドロップダウンから編集を選択します。
  3. 左側のペインでアクセス権限をクリックします。
  4. Alexaイベントを送信する権限を有効にするには、Alexaイベントを送るをオンにします。
  5. Alexaスキルメッセージングで、AlexaクライアントIDAlexaクライアントシークレットをメモしておきます。
    AlexaクライアントIDAlexaクライアントシークレットの値を使って、ユーザーのアクセストークンをリクエストします。
    以下の図は、アクセス権限スライダーと、クライアントIDおよびクライアントシークレットの例です。
    スマートホームのアクセス権限


認証フローを実装する

ユーザーがスキルを有効にしてアカウントリンクを完了した後、AlexaはAcceptGrantディレクティブをスキルに送信します。AcceptGrantディレクティブを処理してLWAの認証を開始するコードをLambda関数に追加します。AcceptGrantメッセージの詳細については、Alexa.Authorizationインターフェースを参照してください。

以下は、Alexaがスキルに送信する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"
      }
    }
  }
}

LWAの認証フローを開始するには、セキュアなHTTP POSTリクエストをhttps://api.amazon.com/auth/o2/tokenに送信します。詳細については、LWA Access Token Requestを参照してください。

以下は、認証リクエストの例です。

クリップボードにコピーされました。

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

リクエスト本文のパラメーターの詳細

パラメーター 説明
grant_type 必須です。付与をリクエストされたアクセスの種類です。authorization_codeである必要があります。
code 必須です。AcceptGrantディレクティブのcodeで与えられた値です。
client_id 必須です。開発者コンソールのアクセス権限セクションに表示されるクライアントIDです。
client_secret 必須です。開発者コンソールのアクセス権限セクションに表示されるクライアントシークレットです。

HTTP応答にはベアラートークンと更新トークンが含まれます。ベアラートークンと更新トークンを格納し、これらのトークンを常にAcceptGrantメッセージのGranteeセクションで識別されるユーザーに関連付けられるようにします。

以下は、正常な認証応答の例です。

 HTTP/1.1 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..."
 }

認証が完了したら、AcceptGrant.Responseを返します。エラーが発生した場合は、ACCEPT_GRANT_FAILEDエラー応答を返します。

イベントでAlexaゲートウェイに送信するトークンを使用する

Alexaイベントゲートウェイに送信するメッセージのscopeでaccess_tokenの値を使用します。エンドポイントは、次のとおりです。

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

以下は、Alexaゲートウェイへのイベントの例です。メッセージには、scopeでHTTP Authorizationヘッダーおよびベアラートークンとして指定された認可トークンが含まれています。

POST /v3/events HTTP/1.1
Host: 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": {}
  }
}

認証フローをテストする

認証フローをテストするには、以下の手順を実施します。

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

  1. 開発者コンソールのテストページで、テストするスキルを有効にします。
  2. Alexaアプリでスキルを有効にし、スキルにアカウントをリンクします。
    リンクが成功すると、Alexaは有効な認可コードとAcceptGrantディレクティブを送信します。

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

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

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

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

1秒間に受け取るトランザクションの数は最大で10個です。その数のメッセージを処理できない場合は、リクエストの際にお知らせください。

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

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

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

認可を取り消す

Alexaが認可Grantを取り消す理由は、次の通りです。

  • ユーザーによってスキルが無効にされた。
  • ユーザーが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から受け取ります。これは永続的な状態であり、ユーザーによって認可が取り消されたことを示しています。詳細については、アクセストークンエラーを参照してください。

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