Auth0の拡張機能でSign In with Appleを実装する方法

#ご注意！
2019/6/18（日本時間）までに、Auth0は「コンソールでぽちぽちやれば連携できる」IdPとして、Sign In with Appleに爆速対応しました！（拍手）
この注を書いている時点では、まだベータ版の機能ではありますが、Facebookやtwitterなど、これまでのソーシャル連携と同じような簡単連携で実装が可能です。
詳しくは、下記のクラスメソッド諏訪さんのブログやAuth0アンバサダー富士榮さんのブログをご参照ください〜。
[【速報】Auth0がSign In with Appleをサポートしました！（ベータ版） #Auth0JP](https://dev.classmethod.jp/server-side/auth0/supported-sign-in-with-apple-beta/?fbclid=IwAR2FAS_k3DDg-pPlvBnL77L8NtQ5iI-ahyf153gGY0o76ddiie3ZdBUxUDk)
[Sign In with Apple連携その後。続々とIDaaSと連携～Auth0編](https://idmlab.eidentity.jp/2019/06/sign-in-with-appleidaasauth0.html?fbclid=IwAR3-YLE0axV6iE44TEVNOnNNgu8RZOSKbX5W5bgi1lFNFzJcMxq8ZHo_tDg)

なので、下記の内容は「ベータ版じゃなかったら、どうやるか」、あるいは「今後新しいIdPが出てきたときの参考」だと思っていただければ幸いです！

#Sign In with Apple+Auth0!
こんにちは！　非技術系出版社で内製化チームをやってます、新人[Auth0 Ambassador](https://auth0.com/ambassador-program)です。
コンソールでポチポチすればソーシャルログイン連携もSSOも簡単に実現できる便利な認証SaaS（IDaaS）、[Auth0](https://auth0.com/jp/)、みなさん使ってますか？

キャンペーンなどで、ちょっとした「おまけサイト」だけどログインが必要、といった場合など、サービス立ち上げ時の認証開発の工数を激減させてくれるのがうれしいところですよね。

さて、認証といえば、先日のWWDC2019で発表され、みなさん気になっているのが、[Sign In with Apple](https://developer.apple.com/sign-in-with-apple/)だと思います。
[Auth0 Blog](https://auth0.com/blog/)で、Abhishek Hingnikarさんが早速、現時点（2019年6月時点）でも簡単にできる実装方法を紹介していましたので、私家版ですが翻訳してお届けします！

原文はこちら→[Implement Sign In with Apple using Auth0 Extensibility](https://auth0.com/blog/implement-sign-in-with-apple-using-auth0-extensibility/) by Abhishek Hingnikar

#前提
- Auth0の基本的なセットアップは済んでいるものとします。まだの方はこちらなどご参照ください。→クラスメソッド諏訪さんのブログ[「認証基盤サービス「Auth0」を使ってみる」https://dev.classmethod.jp/cloud/auth0-overview/](https://dev.classmethod.jp/cloud/auth0-overview/)
- Apple Developerのアカウントは取得している。
- （注：〜）という部分は訳者からの注や補足です。
- 以下は私訳ですので、プロダクションレベルでの使用などに際しては、ご自身でもろもろ確認しながらご利用ください。

#いよいよ本題：ここからが翻訳↓
##Auth0の拡張機能でSign In with Appleを実装する方法

先日木曜日に、（Auth0 Blogにて）WWDC2019で発表されたAppleの新しい認証プロバイダ、[Sign In with Appleについて触れました](https://auth0.com/blog/what-is-sign-in-with-apple-a-new-identity-provider/)（←注：Auth0 Blogでの初報）。

その記事では、Node.jsアプリケーションでSign In with appleに対応する、簡単な手順を示しています。

今回は、Sign In with Appleを、特別なコードを書き加えることなくサポートすることができる方法を紹介しましょう。Auth0のカスタムソーシャルコネクションのおかげで、Appleも、Auth0とつなぎこむことで利用可能な、数ある認証プロバイダのひとつに過ぎなくなる、ということができるのです。

##Auth0のコア機能を拡張する

Auth0 Blogでは、最近もAuth0の[ビジョンと方向性について](https://auth0.com/blog/the-developer-first-identity-platform-auth0-story-and-future/)触れました。

開発者は、ツールやライブラリ、とくに、認証のようなインフラ・コンポーネントによって、制約を受けることを嫌うものです。

Auth0のサービスにおいて、拡張性は標準的な存在であり、これは利用者の87%がAuth0のプラットフォームを拡張して利用しているという事実を反映しています。Auth0が提供する拡張性のポイントのひとつには、連携する認証メソッドをあらたに追加することができる、というものがあります。これが、Sign In with Appleをサポートする際にも利用可能なのです。

##事前準備
Sign In with appleへのサポートを追加するには、カスタムドメインを設定済みのAuth0テナントと、そのドメインでAuth0の認証を利用するよう設定されているウェブアプリケーションが必要です。

Auth0のQuick Startを利用すれば、こうしたアプリケーションをごく簡単ないくつかの手順でセットアップし、走らせることができます。この記事の内容を試すことだけが目的であれば、アプリケーションはNode.js、ASP.NET、Javaなど、どの技術スタックで作られていても構いません。

##Appleに登録する
アプリケーションのセットアップが終わったら、AppleのApp IDとService IDを作る必要があります。その方法については、[前回の記事](https://auth0.com/blog/what-is-sign-in-with-apple-a-new-identity-provider/#Implementing-Sign-In-with-Apple)でも詳しく触れましたが、まとめると以下のようになります。

- Apple Developer Accountを作成する。
- "Certificates, IDs, & Profiles"から"Idenfifiers"を開き、"Register an App ID"へ移動。
- Identifierのタイプとして"App IDs"を選び、"Continue"をクリック。
- アプリの説明とBundle ID（推奨される命名規則はドメインを逆に並べたもの。たとえば、`com.mycustomdomain`）を入力する。
- スクロールして"Sign In with Apple"にチェックを入れ、"Continue"、続いて"Register"をクリック。
- "Certificates, IDs, & Profiles"のセクションに戻り、"Identifiers"という文字列の隣にある青いアイコンをクリック。
- "Service IDs"を選択して、"Continue"をクリック。アプリの説明とIdentifier（たとえば`com.mycustomdomain.webapp`）を入力。
- "Sign In with Apple"を選択したのち、"Configure"をクリック。
- "Web Domain"（今の例では`mycustomdomain.com`）と"Return URL"（`mycustomdomain.com/callback`）を設定。
- "Save"してから"Continue"を押し、続く"Register"をクリック。

Service IDを取得したら、Appleからドメインの確認を受ける必要があります。

- "Certificates, IDs, & Profiles"のページで、新規に作成したService IDをクリック。
- "Sign In with Apple"の項目の隣にある"Configure"ボタンを押し、"Download"をクリック。
- `apple-developer-domain-association.txt`ファイルが落ちてくるので、これをコピーしてサーバに置き、`https://mycustomdomain.com/.well-known/apple-developer-domain-association.txt`でアクセス可能なようにしておく。
- 設置できたら、Service IDの設定ページで"Verify"をクリック。エラーがでなければ、準備完了。

##カスタムソーシャルコネクションの作成

次のステップで、Auth0経由で実装している認証プロバイダにAppleを追加することができます。

Appleに自分のアプリケーションを登録したら、Auth0のダッシュボードを開き、"Extensions"をクリックします。"Custom Social Connections"のエクステンションを探し、インストールしてください。このアプリによって、Sign In with AppleのようなカスタムOAuth/OIDCコネクションを、いくつかの基本的な情報を入れるだけで、手早く追加することができるようになります。

インストールが終わったら、インストール済みのコネクションのリストから"Custom Social Connections"をクリックして、アプリの認証を行なってください。次に、"New Connection"をクリックします。

カスタムコネクションを作成するために必要な情報のほとんどは、ここまでのステップで取得することができています。不足しているclient secretを生成するためには、次の手順を行なってください。

- Apple Developerのダッシュボードで"Certificates, IDs, & Profiles"セクションの"Keys"を開きます。
- 青い丸のアイコンをクリックして、新しいキーを追加します。
- "Key Name"を入力し、"Sign In with Apple"のオプションをチェックします。
- "Configure"をクリックし、"Choose a Primary App ID"のフィールドに自分のApp IDが入力されていることを確認します。
- "Save"、"Continue"、"Register"を順にクリック。
- キーをダウンロードし、アプリのディレクトリに入れて、`authkey.p8`とリネーム。
- このキーから、JWTライブラリを使って、ES256アルゴリズムを用いて、client secretを生成します。下の例はNode.jsを使っていますが、他のプログラミング言語のライブラリを使っても、同様のことができます。

このサンプルスクリプトを使うには、`generate-secret.js`という名前で新しいファイルをキーと同じディレクトリに作成し、以下のコードを記述します。

```generate-secret.js
const jwt = require("jsonwebtoken");
const fs = require("fs");

const privateKey = fs.readFileSync("./authkey.p8");
const token = jwt.sign({}, privateKey, {
 algorithm: "ES256",
 expiresIn: "60 days",
 audience: "https://appleid.apple.com",
 issuer: "TEAM_ID",
 subject: "com.mycustomdomain.webapp"
});

console.log("The token is:", token);
```

*著者注：`com.mycustomdomain.webapp`は自分のService IDのidentifierで置き換えてください。また、`TEAM_ID`は[このリンク先で確認できる](https://developer.apple.com/account/#/membership)自分のteam IDと置き換えてください。*

このスクリプトを実行して、自分のclient secretを生成します。

```js
node generate-secret.js
```

これで、カスタムソーシャルコネクションを完成させるのに必要なものは、ほぼ揃いました！

Auth0のダッシュボードに戻り、カスタムソーシャルコネクションの各フィールドを次のように設定してください。

- Name: `Apple`、または好きな名前に設定。
- Client ID: 自分のService ID identifier、上記の例では`com.mycustomdomain.webapp`。
- Client Secret: 直前のステップで生成した文字列。
- Fetch User Profile Script:

```js

function(accessToken, ctx, cb) {
   const jwt = require('jsonwebtoken');
   // call oauth2 API with the access token and create the profile
   const idToken = ctx.id_token;
   const profile = jwt.decode(idToken);

   profile.id = profile.sub;
   console.log(profile);
   cb(null, profile);
  }
```

- Authorization URL: `https://appleid.apple.com/auth/authorize`
- Token URL: `https://appleid.apple.com/auth/token`
- Scope: `fullName email`
- Custom Headers:

```json

{
   UserAgent: "Auth0",
   Accepts: "application/json"
  }
```
（注：上記は原文通りのjsonなんですが、自分でやってみると「valid jsonじゃない」と怒られてエラーになりました。単純なことなんですが、「"UserAgent"」「"Accepts"」にもダブルクォーテーションをつければ通ります！）

すべて正しく入力できたら、"Save"をクリックして、このコネクションが自分のアプリケーションで利用できるようにします。

設定はこれで完了です！

##Sign In with Appleを使ってみる

ログインを試してみるために、アプリケーションが実行されていることを確認して、サイトを開いてみましょう。ログインページを開くと、次のようなSign In with Appleのオプションが表示されているはずです（注：ここではAuth0標準の`lock`の画面が開いています。Facebookその他のソーシャル連携も同様ですが、Auth0を使うなら、独自のログインUIを作るより、設定ひとつでログイン連携が簡単に実装できる標準UIがオススメです！）。

"Continue with Apple"をクリックし、Apple IDとパスワードを入力します。

新しいデバイスの認証を求められたら、"許可"をクリックしましょう。

次に、認証コードが付与されます。このコードをメモして、"完了"をクリックし、"二段階認証"の画面に今のコードを入力します。

これが済むと、自分の「名前」の編集と、自分のメールアドレスを共有するか、隠すかを選択できる画面に遷移します。選択を行なって、"Continue"をクリックします。

これで、Appleでサインインできました！

##Coming Soon

Auth0では、Sign In with Appleを中心的なインテグレーションに加えるための開発に励んでおり、（注：他のソーシャル連携と同様に）スイッチをポチポチ押すだけで、アプリで簡単にこのログイン方法をサポートできることを目指しています。お楽しみに！

#翻訳は以上となります！
取り急ぎ、画像なしで公開しますが、追って自分で試してみた画面などを加えていきたいと思います。
変換ミスなどあるかもしれませんが、とりあえず速度優先で行ってみます！（2019.6.9 14:55）