Alexaと自分のシステムとでユーザー連携する方法

（2018.6.2 この記事を作ったのはまだ英語ページしかないときでしたが、今みたら公式に日本語のリファレンスができていましたので、今後はそちらをご覧ください。m(__)m ）

https://developer.amazon.com/ja/docs/custom-skills/link-an-alexa-user-with-a-user-in-your-system.html

（2017.4.2書きかけです。）

Linking an Alexa User with a User in Your System
https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/linking-an-alexa-user-with-a-user-in-your-system

> AmazonのAlexaサービスに関する説明の翻訳です。
> 超意訳なんで、怪しいところが多々あります。
> 不明点があったら原文をご参照ください。


#Overview
いくつかのskillは他システム上のユーザー情報との連携を必要とします。*account linking*と呼ばれます。あなたのシステムとAlexaユーザー情報とを紐付けるものだからです。なおSmart Home Skill APIを使うSkill群はAlexaユーザーと*device cloud account*を紐付けるために、必ずaccount linkingを、（authorization code grant flowとともに）使わなければなりません。

例えば、あなたが「Car-Fu」というタクシー配車サービスを運営していたとします。ユーザーにCar-Fuへの音声アクセスを提供するCustom skillは、「"Alexa、Car-Fu にタクシーをオーダーして"」のように頼めばよく、大変便利です。
このリクエストを完了するには、Car-Fuの特定のユーザーとしてCar-Fuサービスにアクセスするskillが必要です。 したがって、Alexaデバイスで使用されるAmazonアカウントとユーザーのCar-Fuアカウントとの間に連携が必要です。

このドキュメントでは、Alexaユーザーとあなたのシステム内のユーザーとの間で連携を確立するための方法を説明します。

ちなみに、アカウントのリンクが必要なのは、スキルが認証を必要とするシステムに接続する必要がある場合のみです。 *custom skill*が該当セッション内だけで属性を使う場合は、アカウントリンクを使用する必要はありません。 その代わりに、リクエスト毎に提供される**userId**を使うことができます。**userId**は、ユーザーがAlexaアプリで自分のスキルを有効にしたときに生成されます。その後ユーザーがskillをdisableするまで、ユーザーからskillへのリクエストの際は同じ**userId**が送信されます。

ヒント：[Alexa Skills Kit SDK for Node.js](https://github.com/alexa/alexa-skills-kit-sdk-for-nodejs)を使用すると、DynamoDBを使用してこのようなデータを保持できます。 これを使用するサンプルスキルについては、[High Low Game](https://github.com/alexa/skill-sample-nodejs-highlowgame)を参照してください。

# How Account Linking Works

## <font color=orange>OAuth Roles and the Alexa Skills Kit</font>

OAuth 2.0では[4つの役割](https://tools.ietf.org/html/rfc6749#section-1.1)があります。**resource owner, resource server, client, および authorization server**です。Alexa Skills KitでOAuthを使う場合の定義は以下となります。

| 種類       |       イメージ |   説明    |
|:-----------------|:------------------|:------------------:|
|Resource owner|<img width="100" alt="user.png" src="https://qiita-image-store.s3.amazonaws.com/0/173392/904768a4-be40-e0dc-bb6c-57979a629697.png">|エンドユーザー|
|Resource server|<img width="100" alt="server.png" src="https://qiita-image-store.s3.amazonaws.com/0/173392/a6bcbc3c-e1a4-f4ef-d9c1-8f65ae2a37b0.png">|使いたいリソースを保管しているサーバー。アクセストークンを使った通信を受け入れる& レスポンスする必要がある。Car-Fuの例で言えば、Car-Fuサービス本体。保護対象はCar-Fu上のアカウント情報。|
|Client|<img width="100" alt="alexaapp_1.png" src="https://qiita-image-store.s3.amazonaws.com/0/173392/32ecbe82-0ae6-45e6-f729-3aa216e8ac5a.png">|ユーザーの代理となって上記Resource serverへアクセスするもの。この例だとAlexa Service。|
|Authorization server|<img width="100" alt="ec2.png" src="https://qiita-image-store.s3.amazonaws.com/0/173392/590ecedd-9a3a-b7b9-3f06-e1dbb1a48ee9.png"><img width="100" alt="server.png" src="https://qiita-image-store.s3.amazonaws.com/0/173392/a6bcbc3c-e1a4-f4ef-d9c1-8f65ae2a37b0.png">|ID認証してアクセストークンを発行する。この例ならCar-Fuサービスの一部。|

Resource serverとAuthorization serverは同じサーバーでも良いです。


## <font color=orange>How End Users Set Up Account Linking for a Skill</font>

ユーザーは自分たちのアカウントをAmazon Alexa appを使ってリンクすることができます。音声だけでリンクを設立することはできないのでアプリを使うのです。以下のような流れとなります。

   - スキルをAlexa app内でEnableにする。
   - 認証が走る。あなたのSkillは`LinkAccount`カードを返し、ユーザーはAlexa appの中でそのカードをつかうことにより先に進む。この方法はcustom skillsでのみ有効であり、smart home skillsでは使えない。


<font color=climzon>implicit grant</font>を使用するか<font color=climzon>authorization code grant</font>を使用するかによって一部のフローは異なりますが、エンドユーザーの手順はどちらでも同じです。

<font color=climzon>authorization code grantのアカウント連携フロー:
（smart home skillsでもCustom skillsでも同じ）

1. ユーザーがAlexa Appの中で該当SkillをEnableにします。
2. Alexa Appの中で、ログインページを表示します。これはデベロッパーポータルでSkillを登録した際に**Authorization URL**に書いたページです。 
companion app（Alexa appのことか？）がこのURLを呼ぶと、`state`, `client_id`, `response_type`, `scope`, 及び `redirect_uri` がクエリ引数として引き渡されます。（下**表2**参照）
3. ユーザーは通常使っているログインアカウントを使用してログインします。
4. あなたのサービス側で、ユーザー認証後に*code*を生成してください。
5. あなたのサービス側で、`redirect_url`にリダイレクトし、その際、URLクエリ引数から`state`と`code`を受け取って引き渡してください。
6. Alexa service側では、返却された情報を検証したのち、あなたの*authorization server*にたいして*access token*と*reflesh token*をリクエストします。その時受け取った`code`を使います。これら両方ともAlexa userに保存されます。
（注；*authorization server*とはデベロッパーポータルで**Access Token URI **に書いたものです。）
7. これにてユーザーのAlexaアカウントはあなたのサービスと連携しました。スキルは使えるようになります。

表2

| 種類       |          説明    |
|:-----------------|:--------------------|
|`state`|Alexa serviceがアカウントリンクされている間つかう。あなたのページはこの値をチェックし、値を返す必要があります。|
|`Client_id`|あなたがデベロッパーポータルでアカウントリンクを設定した時に発行されたものです。|
|`response_type`|"code grant flow"の時だけ使う`code`です。|
|`scope`|要求されたアクセスのレベルを示すアクセススコープの選択肢リストです。あなたはSkillのアカウントリンクを有効にするときにサポートするスコープ群を定義します。|
|`redirect_url`|あなたのサービス上でユーザー認証完了後、どこにリダイレクトするかを示すURLです。|


 <font color=crimzon>implicit grantのアカウント連携フロー (custom skillsのみ):</font>
（自分は使わなそーなので省略）

## <font color=orange>What Happens when a User Invokes a Skill with Account Linking</font>

ユーザーがcustom skillを使えるようになった時、以下のことが起きます。

1. ユーザーはSkillを呼び出せます。例えば、「Alexa、私にタクシーを注文するようにCar-Fuに依頼してください。」
2. もし authorization code grantを使っている場合、Alexa serviceはユーザー用に保存されたアクセストークンがまだ有効であることを確認します。もし有効期限切れの場合、Alexa serviceは新しいアクセストークンをあなたのauthrization serverにリクエストするため、リフレッシュトークンを使います。
3. あなたのSkillあてに送信された`LaunchRequest`あるいは`IntentRequest`には、以前に保存されたユーザーのアクセストークンが含まれます。
4. あなたのサービス上で、トークンが正しいかの検証を行ってください。
    - トークンが有効の場合、あなたのサービス側では必要となるユーザー情報にアクセスし、リクエストに応じて処理を行ってください。その後、喋るべきテキストと、Alexa appに表示するべきcardがあればそれも一緒に返信してください。
    - トークンが無効の場合、リンクを促す文章と、`LinkAccount`カードを返信してください。ユーザーはカード上のlinkをクリックし、連携プロセスを開始することができます。
    - ![cards-account-linking._TTH_.png](https://qiita-image-store.s3.amazonaws.com/0/173392/002225d0-bee2-a9b2-bf4a-af21bf5d9a4b.png)
    - LinkAccountカードの例。

*smart home skills*でも似たような手順となります。
（使わなそーなので省略）
詳しくは[Smart Home Skill API Reference](https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/smart-home-skill-api-reference)を参照してください。

## <font color=orange>What Happens if the User Disables a Skill with Account Linking</font>

ユーザーがAlexa App上でSkillをDisableにした場合、Alexa サービスはアクセストークンを削除します。（リフレッシュトークンもあれば同様に消します。）
これは、ユーザのAlexaアカウントとあなたのサービスのアカウントとの間のリンクを削除することを意味しています。
ユーザーが後でそのスキルを再び有効にする場合、新しいユーザーとしてアカウント連携プロセスを完了する必要があります。

## <font color=orange>What Do You Need to Add Account Linking to Your Skill?</font>

アカウント連携を実装するには、次のものが必要です。

| Authorization Code Grant| Implicit Grant  |
|:--------------------|:---------------------|
|ユーザーを認証するWebベースのサービス。|（同左）|
|ログインページを表示してユーザーの資格情報を収集し、ユーザーを認可した後、*authorization code*を生成する認証サーバー。|ログインページを表示してユーザーの資格情報を収集し、ユーザーを認可し、そのユーザーを一意に識別する*access token*を生成する認証サーバー。|
|authorization codeとAlexaクライアントのクレデンシャルを受け入れ、ユーザーを一意に識別するアクセストークンを生成する認証サーバー。|不要。|

あなたのSkillにアカウント連携をするのは、以下を行う必要があります。

1. [あなたのサービスにアカウント連携のログインページを追加してください。](#adding-account-linking-support-to-your-login-page-authorization-url)
2. [クラウドにてskill用に作ったweb serviceあるいはLambda functionにアカウント連携ロジックを追加してください。](#adding-account-linking-logic-to-the-service-for-your-skill) 
3. [デベロッパーポータルでアカウント連携を有効にしてください。](#enabling-account-linking-for-a-skill-in-the-developer-portal)

それぞれのステップについて詳しく説明します。

# Adding Account Linking Support to Your Login Page (Authorization URL)

アカウント連携プロセスでは最初に、Alexa appがあなたの リソースサーバーへのログインページを表示します。目的に適したページを設計・開発してください。このページでは、ユーザーの資格情報を検証してから、アクセストークンまたはauthorization codeを返却する必要があります。

[デベロッパーポータルでSkillの設定をする際](#enabling-account-linking-for-a-skill-in-the-developer-portal)、このページのURLを**Authorization URL**フィールドに入力してください。


## <font color=orange>Providing the Login Page in the User’s Language</font>

Alexaアプリは、ユーザーのブラウザがサポートされている言語（`en-us`、`en-gb`、または`de-de`）のいずれかに設定されている場合、ユーザーのブラウザ言語設定を使用して、ローカライズ版のアプリを表示しようとします。他の言語では、デフォルトで`en-us`に設定されています。


UXに一貫性をもたせるために、ログインページもAlexaアプリと同じ言語で表示する必要があります。言語を取得するには、まず[`Accept-Language`ヘッダー](https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4)をチェックします。 Alexaアプリは、あなたのサーバーの認証URLを呼び出すときにこれを設定して送りつけます。

ヘッダーが設定されていない場合、ユーザーのブラウザー情報から`navigator.language`または`navigator.browserLanguage`を参照して言語を検知し、使用することもできます。[ナビゲータ言語プロパティ](http://www.w3schools.com/jsref/prop_nav_language.asp)を参照してください。

ユーザーの(スマホの)ブラウザ設定は、ユーザーのAlexa対応デバイスで定義されている言語に依存しないことに注意してください。たとえば、ユーザーはechoやecho dotなどのAlexa対応端末ではドイツ語を使用するように設定していも、ブラウザでは英国の英語を使用するように設定できます。この場合、Alexaアプリは英語でレンダリングされ、`Accept-Language`ヘッダーは英国英語（`en-gb`）に設定されます。


## <font color=orange>Parameters Passed to Your Authorization URL</font>


Alexaアプリは、あなたの**Authorization URL:**を呼び出すときに、URLクエリ文字列に以下のパラメータを含みます：

　　・`state`は、アカウントのリンクプロセスを追跡するためにAlexaサービスによって内部的に使用されます。
　　　　・あなたのページは、リダイレクトURLを呼び出すときに、この値をいじらずに返す必要があります。
　　　　・この値は5分後に失効します。ユーザーがログインしてサービスがユーザーをリダイレクトするのに5分以上かかる場合、`state`は無効になり、アカウントのリンク処理は失敗します。この場合、ユーザーはAlexaアプリのリンクをクリックしてやり直す必要があります。
　　・`client_id`は、あなたが定義した識別子です。これを使用して、アカウント連携で設定したさまざまなスキルを区別するなど、スキル固有の機能をすべて提供できます。デベロッパーポータルでスキルの[アカウント連携を有効にするとき](#enabling-account-linking-for-a-skill-in-the-developer-portal)に、`client_id`を定義してください。
　　・`response_type`の値は、authorization code grantかimplicit grantか、どちらを使用するかによって異なります。
　　　　・authorization code grantの場合は`code`
　　　　・implicit grantの場合は`token`
　　・`scope`は、Alexaユーザーが必要な権限を示すリストです。デベロッパーポータルでSkillの[アカウント連携を有効にするとき](#enabling-account-linking-for-a-skill-in-the-developer-portal)、これらの`scope`を定義します。
　　　　・この情報は、アクセストークンを生成するときに使用できます。たとえば、リソースサーバーの基本プロファイル情報にアクセスできるトークンを作成できますが、支払い情報へのアクセスは許可されません。
　　　　・複数のスコープを使用できます。リストは、URLエンコードされた半角スペースで区切られます。
　　　　・アカウント連携でどのような権限が付与されるかをユーザーに伝えることもできます。たとえば、ログインページには、「これにより、Car-Fuスキルは、あなたの代わりにタクシーを発注し、料金をアカウントに請求することができます」というようなテキストを表示することができます。
　　・`redirect_uri`は、ユーザーの認証後にサービスがユーザーをリダイレクトするAmazon固有のリダイレクトURL（[OAuth Redirection Endpoint](https://tools.ietf.org/html/rfc6749#section-3.1.2)）です。このパラメータに期待できる値は、アカウントリンクの設定時に開発者ポータルにも表示されるため、URLが有効であることを確認できます。



たとえば、ページの承認URLが`https://www.carfu.com/login`の場合、Alexaアプリから呼び出されるURLは、次のようになります（認証コードの付与(authorization code grant)用）。

``` https://www.carfu.com/login?state=abc&client_id=alexa-skill&scope=order_car%20basic_profile&response_type=code&redirect_uri=https%3A%2F%2Fpitangui.amazon.com%2Fspa%2Fskill%2Faccount-linking-status.html%3FvendorId%3DAAAAAAAAAAAAAA ```


## <font color=orange>Requirements for Your Login Page</font>

ログインページは次の要件を満たしている必要があります。


　　・HTTPS経由で提供される必要があります。
　　・Alexaアプリ内に表示されるため、モバイルフレンドリーでなければなりません。
　　・ページでポップアップウィンドウを開くことはできません。
　　・ユーザーのクレデンシャル(ID/Pssのことか?)を受け入れ、ユーザーを認証する必要があります。
　　・それは次のいずれかでなければならない：
　　　　・リソースサーバー(自分のシステム）上で、ユーザーを一意に識別するアクセストークンを生成する。
　　　　・アクセストークンを取得するために、あなたのauthorizationサーバーに渡すauthorization code認証コードを生成する。（？？）
　　・クエリ引数に渡されるステータスをトラッキングする必要があります。（？？）
　　・ユーザーを認証した後、ページは2つのAmazon提供のリダイレクトURLのいずれかにユーザーをリダイレクトする必要があります。
　　　　・使用するリダイレクトURLは、`redirect_uri`パラメータとして認可リクエストに含まれます。
　　　　・スキルの[アカウント連携オプションをオンにすると](#enabling-account-linking-for-a-skill-in-the-developer-portal)、2つのリダイレクトURLがデベロッパーポータルにも表示されるので、ログインページで`redirect_uri`パラメータに期待される値を確認できます。
　　　　・authorization code grant(=承認コード付与)の場合は、`state`と`code`をURLクエリ文字列に含めます。
　　　　・implicit grant(=暗黙の許可)の場合は、URLフラグメントに`state`、`access_token`、および`token_type`が含まれます。 `token_type`は`Bearer`でなければなりません。

たとえば、Amazon提供のリダイレクトURLが次のようなものであったとします:

``` https://pitangui.amazon.com/spa/skill/account-linking-status.html?vendorId=AAAAAAAAAAAAAA ```

認可コード付与(= authorization code grant)の場合、リダイレクトURLは次のようになります。

``` https://pitangui.amazon.com/spa/skill/account-linking-status.html?vendorId=AAAAAAAAAAAAAA&state=xyz&code=SplxlOBeZQQYbYS6WxSbIA ```

渡す必要があるパラメータ（`state`と`code`）は、URLのクエリ文字列部分にあります。

一方、暗黙の許可(=implicit grant)の場合、リダイレクトURLは次のようになります。

``` https://pitangui.amazon.com/spa/skill/account-linking-status.html?vendorId=AAAAAAAAAAAAAA#state=xyz&access_token=2YotnFZFEjr1zCsicMWpAA&token_type=Bearer ```

戻さなければならないパラメータ（`state`、`access_token`、および`token_type`）は、URLの*URLフラグメント*部分にあります。これは、ハッシュタグ（`＃`）の後の部分です。



# About Access and Refresh Tokens


あなたのauthorization server(=認証サーバー)は、システム内のユーザーを一意に識別する[アクセストークン](https://tools.ietf.org/html/rfc6750)を提供する必要があります。

 authorization code grant(=認可コード付与)の場合、Alexaサービスはauthorization server（=開発者ポータル上で**Access Token URI** として指定されている、あなたのシステムの認証サーバー）を呼び出し、`code`とクライアントのクレデンシャルを渡します。そのとき認証サーバーは、アクセストークンとオプションのリフレッシュトークンを返さなければなりません。リフレッシュトークンの返却は任意ですが、アクセストークンが期限切れになった場合、Alexaサービスがこのリフレッシュ・トークンを使用して新しいアクセス・トークンを取得する時のためには、生成して返却しておいたほうが良いです。

implicit grant(=暗黙の許可)の場合、ログインページには、上記のリダイレクトURIの例が示すように、リダイレクトURLを呼び出すときのアクセストークンが含まれています。implicit grantはリフレッシュトークンをサポートしていないため、トークンが期限切れになった場合、エンドユーザーはアカウントを再リンクする必要があります。

どちらのタイプでも、アクセストークンを生成するときは、リソースサーバー固有のトークンを指定します。<font color=hotpink> GoogleやFacebookなどの他のOAuthプロバイダが提供するアクセストークンは使用しないでください。</font>セキュリティのために、トークンはユーザーを識別する値であり、かつ、推測できてはいけません。


# Adding Account Linking Logic to the Service for Your Skill


skillにアカウント連携を追加するには、skillに送信されたリクエストに含まれるアクセストークンを確認して使用するロジックをコーディングする必要があります。

## <font color=orange>Getting the Access Token from the Request (Custom Skills)</font>


Javaライブラリを使用する場合、`onIntent()`、`onLaunch()`および`onSessionEnded()`メソッドに渡される`Session`オブジェクトでアクセストークンを使用できます。まず`Session.getUser()`メソッドを使用して`User`を取得し、次に`User.getAccessToken()`を呼び出してトークンを取得すれば良いです。

JSONでは、リクエスト内の`user`オブジェクトの`accessToken`プロパティでアクセストークンを使用できます。

```JSON
{
  "version": "string",
  "session": {
    "new": boolean,
    "sessionId": "string",
    "application": {
      "applicationId": "string"
    },
    "attributes": {
      "string": object
    },
    "user": {
      "userId": "string",
      "accessToken": "string"
    }
  },
  "request": object
}
```


## <font color=orange>Getting the Access Token from the Request (Smart Home Skills)</font>

アクセストークンは、`payload`オブジェクトの`accessToken`プロパティで、device directiveの一部としてスキルアダプタに送信されます。
たとえば、この`DiscoverAppliancesRequest`directiveに注意してください:

```JSON
{
  "header": {
    "namespace": "Alexa.ConnectedHome.Discovery",
    "name": "DiscoverAppliancesRequest",
    "payloadVersion": "2",
    "messageId": "6d6d6e14-8aee-473e-8c24-0d31ff9c17a2"
  },
  "payload": {
    "accessToken": "string"
  }
}
```


## <font color=orange>Validating the Access Token</font>


認証要求に対して、コード上では少なくとも2つのチェックを行う必要があります。

1. `accessToken`が存在することを確認します（カスタムスキルのみ）。
ユーザーが正常にアカウント連携していない場合、Javaライブラリ使用時であれば`User.getAccessToken()`が`null`を返します。JSON使用時であれば`accessToken`プロパティは存在しません。なおこのチェックはスマートホームスキルには適用されません。
2. `accessToken`が存在していた場合は、それが有効であることを確認し、リソースサーバー内のユーザーを識別します。トークンが存在していてもさまざまな理由で無効だったりするので注意してください。たとえば、

　　・ユーザーがサービス側のアカウントを解約した場合。たとえば、AlexaユーザーがCar-Fuとのアカウントリンクを設定し、その後Car-Fuアカウントを解約した時はこれにあたります。この時点で、Alexaサービスによって格納されたトークンは、存在しないユーザーとなってしまいます。
　　・トークンの有効期限が切れており、新しいトークンも取得できない場合。あなたのサーバーがauthorization code grant方式だがリフレッシュトークンを返却しなかった場合や、そもそもリフレッシュ・トークンをサポートしていないimplicit grantを使用している場合に該当します。

トークンが有効な場合、スキルは要求を正常に処理し、必要に応じてリソースサーバーからデータにアクセスできます。 Car-Fuの例では、スキルはユーザーのプロフィールと支払い情報をCar-Fuサービスから取得し、車を注文し、ユーザーに確認を返します。レスポンスの返却の詳細については、Alexaが送信したリクエストの処理の「[レスポンスの返却](https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/handling-requests-sent-by-alexa)」を参照してください。


## <font color=orange>Responding to an Invalid Access Token (Smart Home Skills)</font>


スマートホームスキルのスキルアダプタに送信されたアクセストークンが無効な場合は、`DependentServiceUnavailableError`を返します。その後、Alexaはユーザーに要求を完了できなかったことを伝えます。



## <font color=orange>Responding to an Invalid or Non-existent Access Token (Custom Skills)</font>


カスタムスキルに送信されたアクセストークンが存在しないか無効である場合、スキルは次の内容を含む応答を返す必要があります。


　　・音声読み上げ用のテキスト。この機能を使用するために、アカウント連携する必要があることをユーザーに説明する内容を記載してください。
　　・*リンクアカウントカード*。これは、ユーザーに自分のアカウントをリンクさせる特別なタイプのカードです。 Alexaアプリに表示されると、このカードにログインページのURLへのリンクが表示されます。ユーザーはこのカードからアカウント連携プロセスを開始することができます。

*リンクアカウントカード*を送信するには：

　　・Javaライブラリを使用する場合は、`LinkAccountCard`クラスのインスタンスを作成し、レスポンスにカードとして含めます。
　　・JSONを使用する場合は、カードタイプを`LinkAccount`に設定します。

以下はJSONの例）

```Json:
 {
     "version": "1.0",
     "sessionAttributes": {
       ...(session attributes not shown)
     },
     "response": {
       "outputSpeech": {
         "type": "PlainText",
         "text": "You must have a Car-Fu account to use this skill. Please use the Alexa app to link your Amazon account with your Car-Fu Account."
       },
       "card": {
         "type": "LinkAccount"
       },
       "shouldEndSession": true
     }
 }
```
ほとんどの場合、ユーザーはアカウントを連携するまでリクエストを続行できないため、この応答はセッションを終了する必要があります。スキルに認証を必要としない意図が含まれている場合は、ユーザーに別の質問をしてセッションを開いたままにしておくとよいでしょう。

## <font color=orange>When to Require a Valid Access Token</font>

あなたのサービスは、ユーザーがあなたのWebサイトで認証することを要求するすべての要求に対してaccessTokenを検証する必要があります。

スマートホームスキルの場合、これにはすべての指示が含まれます。

カスタムスキルの場合、通常はほとんどのインテントが含まれますが、認証を必要としないインテントを持つことができます。たとえば、Car-Fuカスタムスキルでは、自動車の発注にユーザー認証が必要な場合がありますが、特定の都市でサービスが利用可能かどうかを尋ねる認証は必要ありません。したがって、このスキルのコードでは次のことが行われる可能性があります:

　　・`OrderTaxi`インテントのハンドラーは、有効な`accessToken`をチェックし、そのトークンを使用してユーザーのCar-Fuプロファイルを取得し、車を注文すること。
　　・一般的な`TaxiAvailabilityByCity`インテントのハンドラは、`accessToken`をチェックする必要はありませんが、Car-Fuサービスで一般情報を検索し、応答を返すこと。

# Enabling Account Linking for a Skill in the Developer Portal


アカウントリンクは、[Amazon Developer Portal](https://developer.amazon.com/edw/home.html#/)の「設定」ページで有効にします。


通常どおりデベロッパーポータルでSkillを登録したら、** Configuration**ページに移動し、**Account Linking or Creation. **で**Yes**を選択します。なおスマートホームスキルではこの選択画面は表示されません。（スマートホームスキルの場合はデフォルトがアカウント連携だから。）

アカウント連携を有効にするには、最低限以下を入力してください。


　　・`Authorization URL`:ウェブサイトのログインページのURL。ユーザーがアカウントをリンクするときにこのページがどのように使用されるかについては、[ログインページにアカウント連携サポートを追加する](#adding-account-linking-support-to-your-login-page-authorization-url)を参照してください。

　　・`Client Id`:ログインページがあなたのスキルからのリクエストであることを認識するために使用するID。この値は、`Client Id`パラメータのauthorization URLに渡されます。authorization code grantを使用する場合、この値は**Access Token URI**からアクセストークンを要求する際にAlexaサービスが含むクライアントクレデンシャルの一部です。

　　・`Authorization Grant Type`:(=認証付与タイプ):アクセストークンを取得するために使用するOAuth 2.0のタイプ。 Alexaスキルキットは2つのタイプをサポートしています：
　　　　・`Implicit grant` （カスタムスキルで使用可）
　　　　・`Authorization code grant`（カスタムスキルまたはスマートホームスキルで使用可）
　　・`Authorization code grantの場合、以下の欄も記入する必要があります。


　　　　・`Access Token URI:`アクセストークンを提供する認証サーバーのURL。
　　　　・`Client Secret:`AlexaサービスがアクセストークンURIで認証できるように、ユーザーが指定する資格情報。これは**client ID**と組み合わせて、Alexaからの要求を識別します。
　　　　・`Client Authentication Scheme`は、アクセストークンURIからトークンを要求する際にAlexaが使用する[認証のタイプ]https://tools.ietf.org/html/rfc6749#section-2.3.1)を識別します。

　　・`Privacy Policy URL:`プライバシーポリシーのあるページのURL。このリンクはAlexaアプリに表示されます。アカウント連携を使用するスキルでは必要です。ここで入力したURLは、**Privacy＆Compliance**ページの**Privacy Policy URL***フィールドにも表示されます。


ログインページが他のドメインのコンテンツを使う場合は、**Domain List**にそれらのドメインを入力します。（（ログインページに貼る画像とかだね。）） authorization URLで登録したドメインは書く必要はありません。たとえば、authorization URLが`https://www.carfu.com/login`であるとします。このページが`www.carfu.com`以外のドメインのコンテンツ（画像など）を取得した場合は、それらを**Domain List**に追加してください。

リソースサーバーが異なるスコープのアクセスをサポートしている場合は、それらを**Scope**リストに入力します。 Alexaアプリがあなたのauthorization URLを呼び出すと、ここに入力されたすべてのスコープがscopeパラメータに含まれます。

## <font color=orange>Redirect URL Values</font>

アカウントのリンクを有効にすると、**Redirect URL**が表示されます。これは、ログインページが認証後にユーザーをリダイレクトする必要があるURLです。この値は、** Authorization URL**に含まれる`redirect_uri`パラメータとしてログインページにも渡されます。

複数の**Redirect URL**が存在することに注意してください。 Alexaアプリは、ユーザーがデバイスを登録した場所に基づいて使用する値を**Authorization URL **に渡します。（（どうやら北米とヨーロッパで２種類みたいです。言語設定と連動しており、間違ったほうを指定した場合は動かないので、両方試してみる必要あり。））


> 注：スキルを[複数の地域に分散](https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/developing-skills-in-multiple-languages#distribution)させる場合、その地域固有の**Redirect URL**を使用する必要があります。前述のように、使用するURLは、`redirect_uri`パラメータのログインページへの呼び出しに含まれています。（？？）


認証後にユーザーをリダイレクトするときにページに含める必要があるパラメーターは、authorization code grant か implicit grantのどちらを使用しているかによって異なります。[ログインページの要件](https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/linking-an-alexa-user-with-a-user-in-your-system#h3_login_req)を参照してください。

>注：アカウント連携を有効にしたskillがエンドユーザーに認定されて公開されると、そのスキルのアカウント連携を無効にすることはできません。

# Next Steps

Coding topics (custom skills):
　　・[Handling Requests Sent by Alexa](https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/handling-requests-sent-by-alexa)
　　・[Including a Card in Your Skill’s Response](https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/providing-home-cards-for-the-amazon-alexa-app)
　　・[Implementing the Built-in Intents](https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/implementing-the-built-in-intents)
Other topics:
　　・Next: [Testing a Custom Skill](https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/testing-an-alexa-skill)
　　・Return to: [Steps to Build a Custom Skill](https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/overviews/steps-to-build-a-custom-skill)
Reference materials:
　　・[JSON Interface Reference for Custom Skills](https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/alexa-skills-kit-interface-reference)
　　・[Custom Skill Java Library Reference](https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/javadocs/alexa-skills-kit-java-library-reference)
　　・[Smart Home Skill API Reference](https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/smart-home-skill-api-reference)