ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。
-
「Appleでサインイン」エクスペリエンスを強化する
「Appleでサインイン」を利用して、Appで安全かつ高速な認証を実現させる方法をご覧ください。パスワードベースのアカウントをセキュアなシングルタップログインの認証にアップグレードする方法や、Appでのユーザーセッションの変更をシームレスに処理する方法を紹介します。また、Webや他のプラットフォームでも「Appleにサインイン」を利用することができるようになります。 このセッションを最大限に活用するには、「Appleにサインイン」やREST APIに関する知識を習得しておくとよいでしょう。また、JavaScriptの基本的な知識を習得しておくこともお勧めします。
リソース
関連ビデオ
WWDC22
WWDC20
-
ダウンロード
こんにちは アカウント体験 チームに所属している エンジニアのRamです 今回は同僚のPatrickと 一緒に Appの Appleでサインイン体験を 向上させる 方法についてお話します iOS13 でAppleでサインインが 導入されてから 迅速で簡単なアカウント 設定とサインインが好評です わずか数行のコードで フォームやパスワードのない ワンタップでの迅速な アカウント設定が 可能になりました Appleアカウントで サインインは ユーザーのApple IDを 保護するために使われている 強力な2ファクタ認証で 保護されています ユーザーとのコミュニケーションをとる 必要がある場合 Appleでサインインを使えば すぐに使える メールアドレスが 入手できます 追加認証は必要ありません Appleでサインインを使用する ことで そのユーザーが 実在する人物かどうかの 指標にもなり 詐欺対策にもなります Appleでサインインすると 勤務先と学校で使用されている 管理対象のApple IDを含め あらゆる場所で利用できます 勤務先と学校のアカウントと統合する 方法について「勤務先と学校での Appleでサインインについて」 をご覧ください このセッションでは Appleでサインインを より効率的にする 方法についてご紹介します Appの既存の認証情報を チェックすることで アカウント重複の防止をする 方法について説明します 次に Apple ID認証情報に ついて深く掘り下げ 認証情報の変更をモニタリングして アカウントの削除などの シナリオを処理する方法に ついて説明します そして最後に Patrickが Appleでサインインを Webやその他プラットフォームで 統合する方法を説明します さあ はじめましょう Appleでサインインは 従来のユーザー名と パスワードによる認証に 代わる便利で安全ですが ユーザーはパスワードでアンロックする アカウントを持っている可能性もあります もし ユーザーが既に アカウントを持っている場合 Appのために2つ目の アカウントを作らないことが重要です サインイン時に正しい判断を できるように 導く方法を見ていきましょう
これは JuiceというサンプルAppで Appleでサインインを使います この動画の関連リンクに ソースコードがあります
Juiceへのサインインは 従来のメールアドレスと パスワードかAppleで サインインを使います ユーザーが認証情報を すでに持っている場合は アカウントへのサインインは あなたの手にかかっています まず最初にパスワードの 自動入力を実装し 既存のパスワード 認証情報を キーボードに 表示するようにします
これにより ユーザーはワンタップで 認証情報を自動入力できます
また パスワードベースの アカウントを アップグレードするために Appleでサインインを使用するよう ユーザーを誘導しましょう アップグレードすると セキュリティが 組み込まれたアカウントに することができ 記憶しなければならない パスワードが一つ減ることになります この実装は アカウント認証 変更拡張子で行われます 拡張機能ベースのAPIは Appleでサインインを使い サインイン方法を アップグレードするための シームレスな体験を ユーザーに提供します
ユーザーのアカウントに 安全なアップグレードを 提供するための詳細は ドキュメント「Appleで サインインを最大限に活用する」 および「ワンタップでできる アカウントの安全なアップ グレード」をご覧ください
パスワードの自動入力を 提供するだけでなく Appの起動と同時に 既存の認証情報を 提示することで さらに一歩 踏み込むことができます これにより ユーザーは ログイン画面に入る前に 正しいアカウントで サインインすることが できます Authentication Services APIは このように実に柔軟です APIを使うと ユーザーが Appleでサインインの 認証情報を作成できるほか パスワードベースの 認証情報を含む 既存の認証情報を 提示することも可能です
これを採用することは 実に簡単です これを実現するための コードをご覧ください すでにAuthentication Services APIを使用している場合 このコードは とても 身近に感じられるはずです
まず ASAuthorizationControllerの インスタンスを作成し ASAuthorizationAppleIDProviderと ASAuthorizationPasswordProvider の両方を 認証リクエスト配列に追加します 次に デリゲートと インターフェイスの提示を 行うオブジェクトを 設定する必要があります そして最後に 認証コントローラで AvailableCredentials オプションを指定して performRequestsを呼び出します このオプションはiOS16に 新たに追加されました システムに対して すぐに利用可能な 認証情報のみが 必要であることを伝えます App起動時の呼び出しを 想定しています
以前のiOSバージョンに 対応させたい場合 performRequestsを 使うことができます これを実行すると 既存の認証情報の リストが表示されます ユーザーは 既存の Appleでサインインの認証情報 または 既存のパスワード 認証情報から選択できます ユーザーが認証情報を 選択した後 システムは ASAuthorizationController デリゲートに対して didCompleteWithAuthorizationを 呼び出します ユーザーがAppleでサインインを 選択した際は appleIDCredentialで 続行します ユーザーがパスワード ベースのアカウントを選んだ場合は passwordCredentialが 返されます ユーザーが既存の認証情報を 持っていない場合 APIはユーザーに Appleでサインインの アカウントを 作成するよう提示しません 代わりに didCompleteWithErrorを呼び出します この場合は 標準的なログインフローを 表示する必要があります ちなみに 同じAuthentication Services APIは パスキーについても シームレスに動作します パスワードに代わる 次世代認証技術である パスキーについて 詳しく知りたい方は 「パスキーについて」 セッションをご覧ください ほんの数行のコードで サインインの体験を フルに活用できます これで ユーザーが正しい アカウントを選択でき 重複してアカウントが 作成されるのを 防ぐことができます
次に Apple ID認証情報を 深堀りしたいと思います
ご存知のように Appleでサインインを使い 認証に成功した後に 得られるレスポンスは ASAuthorizationAppleIDCredential オブジェクトです user fullName email realUserStatus identityToken authorizationCodeなどの 値が含まれます それぞれについて 簡単に説明します userとは一意の 永続的なIDです 開発者チームのすべての Appに共通するIDです
システム内のユーザーを 一意に識別するために使用します fullNameは必要な時だけ 聞いてください リクエストされると ユーザーは任意の名前を共有できます ユーザーとの コミュニケーションには emailをお勧めします ユーザーには 2つの選択肢があります 1つ目はApple IDに関連付けられた メールを共有することです もう一つは 「メールを非公開」 を使います これにより非公開のメールアドレスが作成され ユーザーの受信トレイに転送されます 双方向リレーで 返信も可能です
どちらの選択肢を選んでも メールアドレスはAppleに 事前に確認され すぐに使用できます また すべてのアカウントに 関連するメールアドレスが あるわけではないので メールを要求しても 値がないシナリオに 対応できるように 準備してください
RealUserStatusは 信頼度の高い指標で、実在する人物かを 示します プライバシーに配慮しながら デバイス上の機械学習 アカウント履歴 ハードウェア認証を 使用して計算されます 実際のユーザーステータスは 3つのタイプがあります 「Likely real」とはユーザーが 実在する人物に見えるという意味です CAPTCHAのような追加の 不正確認チェックを スキップするなど ユーザーに最高の 体験を提供しましょう 「Unknown」とは システムが ユーザーを実在の人物か 判断していないという意味です 追加の検証手順を必要とする 限られた情報のアカウントと 同様に、ユーザーを信頼しましょう そのユーザーは 実在する可能性があるので Appの利用を ブロックしないでください
最後に「unsupported」とは システムが この判定を行うことが できないことを意味します fullName email realUserStatus などの プロパティは アカウントが 初めて作成されたときだけ 返されることを ここで触れておきます
そのため アカウントが 作成されたことを 確認できるまで fullName emailなどの プロパティを安全に キャッシュすることが必要です
identityTokenは Appサーバーが必要とする データのほとんどを含む JSON Webトークンです これは業界標準の 認証アプローチです JSON Webトークン またはJWTの3つから構成されます base-64 URL エンコードされたヘッダー base-64 URL エンコードされたペイロード および Appleによって 署名されたサインです Appleの公開鍵で 署名を検証し 改ざんされていないことを 確認する必要があります Apple IDサーバからの 応答であることを確認します また 同様に重要なのが Appサーバーがトークンの 有無を確認することです ペイロードをデコードしたら 発行元が appleid.apple.comであるか オーディエンスフィールドが AppのバンドルIDか 有効期限タイムスタンプが 現在時刻よりも大きいことを確認して トークンが 有効であることを確認します サブジェクトは ユーザーIDになります もし あなたが リクエストした場合 ユーザーの メールアドレスも含まれます realUserStatusも 確認できます 値は「unsupported」の場合は 0になります 1は「unknown」 2は「likely real」です そして最後に nonceが 認証リクエストの作成前に 生成されたものと同じで あることを確認します
nonceの詳細と リプレイ攻撃を軽減のため 認証プロセスを 安全にする方法については 「Appleでサインインの 最大活用」の セッションをご覧ください
AuthorizationCodeは リフレッシュトークンと 引き換えにApple ID サーバーに提供できる 短命で1回しか 使用できないトークンです OAuth 2.0などの オープンスタンダードを すでに利用している システムであれば 馴染みのある 話かもしれません リフレッシュトークンを 生成するには auth/tokenエンドポイントにポスト リクエストを送信する必要があります クライアントIDと クライアントシークレットを 受け取ったばかりの 認証コードと共に渡します クライアントシークレットの 作成方法の詳細は Appleデベロッパの ドキュメントで確認できます レスポンスで リフレッシュトークン アクセストークン 新しいIDトークンを取得します 先ほど受け取ったもの同様ですね 期限切れのアクセス トークンがある場合 リフレッシュトークンを 使って 同じエンドポイントから 新しいアクセストークンを 取得できます また 同じリフレッシュ トークンを無効に なるまで 使い続けることも可能です リフレッシュトークンは トークン認証に失敗した時や ユーザーのセッションに 変更があった場合に 無効となる 可能性があります
ユーザーセッションと いえば 次に 認証情報の状態に 関する変更の処理と モニタリングについてお話します IDトークンの検証後 Appにはユーザーセッションを 管理する責任があります
ユーザーセッションが 変更されるシナリオはさまざまです ユーザーが設定からAppの Apple IDの使用を停止したり デバイスから サインアウトした可能性もあります セッションの変更を柔軟に処理するために getCredentialState (forUserID:)を ASAuthorizationAppleID Providerで呼び出します このAPIは Appが起動したら すぐに呼び出すことが 推奨されています または 状態を確認したい 時に呼び出します またcredentialRevoked Notificationを監視して 認証が無効になったらAppに 通知されるようにします 状態の変化を観察したら 別のユーザーがサインイン していると考えるべきです 現在のユーザーをAppから サインアウトさせます Appサーバーがある場合 サーバ間通知に 登録する必要があります サーバーにはユーザーと アカウントについて 重要なアップデートが届きます 通知はAppのグループごとに 送信されます 以下のシナリオが 想定されます ユーザーがメール転送設定を 無効または有効にしたとき ユーザーがAppで AppleIDの使用をやめたとき または ユーザーがAppleIDを 永久的に削除したとき 通知の受信を開始するには まず Appleデベロッパ ポータルに エンドポイントURLを 登録する必要があります すべてのイベントは同じ エンドポイントURLに届きます イベントは Appleによって署名された JSON Webトークンとして送信されます メール転送が無効になった場合 JWTのペイロードで email-disabledイベントを 受信します
AppでAppleIDの使用を やめた場合 consent-revokedイベントを 受信します このイベントが発生したら アクティブな ユーザーセッションを 無効化することが重要です
また ユーザーがAppleIDを 削除した場合は account-deleteのイベントを 受信します 繰り返しになりますが アクティブなユーザー セッションを無効にし 更新してください
次はアカウント削除に 焦点を当ててみましょう アカウントは私たちの アイデンティティの一部です そのアカウントで個人的な データ管理のため使われます アカウントを削除したい人が いるかもしれません これをサポートする 必要があります
アカウントの削除方法を 提供する必要があり あなたのApp内で 削除方法を用意する必要があります 削除のプロセス全体を 管理することは あなたの責任です
ユーザー情報を保存している Appサーバーがある場合 通常 Appがサーバーに ユーザーアカウントの削除について 通知します Appleでサインインを 削除のプロセスに 含めることができます これは Appに 関連付けられたアカウントを 削除するためにサーバーが 使用できる新しいREST エンドポイントを 使い実行します このAPIを簡単に説明します アカウントを 削除するためには そのユーザーに対して 有効なリフレッシュトークンか アクセストークンが必要です どちらのトークンも 持っていない場合は auth/tokenエンドポイントを 使用して生成できます どちらかのトークンを 取得したら 必要なパラメータを指定して auth/revoke エンドポイントを 使用できます リフレッシュトークンを 使用する場合は トークンタイプを REFRESH_TOKENに設定します
アクセストークンを使って 削除する場合 トークンタイプを ACCESS_TOKENに設定します 応答が成功した場合 トークンとユーザーの アクティブセッションが 即座に無効になります
一度削除されると ユーザーがAppに戻り Appleでサインインを 使用すると Appで最初にアカウントを 作成したときと同様の 体験をすることになります
それでは サインアウトして 同僚のPatrickに 引き継ぎ Webやプラットフォームで Appleでサインインを どのように使うかについて 説明してもらいます
ありがとう Ram Appleでサインインが すべてのプラットフォームで シームレスに機能することは 多くの人々に愛されています しかし それだけでは終わりません Appleでサインインは Webや他のプラットフォームでも シームレスに機能します Appleでサインインの 体験を向上させる 方法についてお話します
先ほど Ramが紹介した Juiceという iOS Appがあります Webにも展開することで より多くのユーザーに Juiceを届けたいと思います まず 似たようなAppを グループ化する方法から 説明します
ユーザー体験を 効率化するために 関連した Appをグループ化することを おすすめしています 関連するAppを グループ化することで ユーザーは一度の同意で Appに情報を 共有することができます
例えば AppはiOSと macOSで利用可能ですが プラットフォームごとに異なる バンドルIDを使用しているかもしれません こうしたAppのグループ化を おすすめします Appleでサインインを 使用する場合 プライマリAppとして 設定したAppの アイコンが表示されます Appleでサインインを サポートするために サービスIDを 設定する方法を説明します まず Appleデベロッパ ポータルにログインします 「Certificates, Identifiers & Profiles」に移動します
Services IDsの隣にある ラジオボタンを選択し 「Continue」を クリックします
サービスの説明を 入力してください
サービスの一意な IDを入力してください そして 「Continue」をクリックします
Sign in with Appleの 横のチェックボックスを クリックし 「Configure」をクリックします Web認証の設定の画面を 表示します Primary App IDをドロップダウン メニューから選択します
次にAppleでサインインをサポートするために Webサイトが使用する ドメインとサブドメインを入力します 最後に Appleの認証成功後に AppやWebにリダイレクト URLを入力してください 以上です Webサイトで Appleでサインインを サポートするために サービスIDを設定しました WebサイトがAppleで サインインに対応していると ユーザーに示すための ボタンが必要です Appleはボタン画像を 生成するために 高度に設定可能な ボタンAPIを提供しています
これを使えば AppやWebサイトで カスタマイズしたボタンを 埋め込むことができます Apple JSでサインイン は シンプルなJavascriptの フレームワークです Web上で簡単に統合できます AppやWebで Appleでサインイン JavaScript フレームワークを 組み込むことから 始めてください このシンプルなAPIを 利用することで ユーザーを認証し DIV一つで作成できる Appleでサインイン ボタンのような 様々なアセットを 取得することができます また ボタンのプロパティを 変更することで AppやWebに合わせて カスタマイズもできます
例えば 現在のプロパティでは 白い「Appleでサインイン」 ボタンが表示されます 境界線とデフォルトの コーナー半径で表示されます data-colorプロパティを 変更することで ボタンの背景色を 変更することができます データ型を「continue」に 変更するとボタンの テキストが更新され 次のように表示されます 「Continue with Apple」
また ロゴのみのボタンを 作成することもできます データモードプロパティを 「logo-only」に設定します Appleでサインイン JavascriptボタンAPIは 他にもさまざまな プロパティを提供します Appleでサインインボタンについての リソースを参照して さまざまなオプションを簡単に 設定できます
REST APIを使用して Appleでサインインのボタンを 生成したい場合は Apple IDボタンの エンドポイントの1つを 使用して ボタンを生成できます 中央揃え 左揃え ロゴボタン用に それぞれの エンドポイントが用意されています クエリパラメータを使用して ボタンをカスタマイズできます この例のリクエストでは 白い Appleでサインイン 境界線ボタンを カスタマイズしています 応答では カスタマイズボタンを PNG画像として受信します Appleでサインインボタンを パーソナライズしたら 次は ユーザー認証です Appleに必要なパラメータを 含む認証リクエストを 送信する必要があります これらは ユーザーのログインを 成功させるために 必要なパラメータです
すでにプラットフォームで Appleでサインインを実装しているため これらのパラメータは 非常に身近なものです
まず クライアントIDを 設定します これがサービスIDに なります Appleデベロッパ ポータルで作成した サービスIDとなります
次に AppやWebで メールや名前が 必要な場合「scope」 パラメータを書き込みます 複数スコープを要求する時 それぞれスペースで区切ります 必要なデータのみを 要求することが重要です
RedirectURIパラメータには Appleデベロッパ ポータルで事前に登録した URLを追加します これは あなたのどのWebサイトに ユーザーを誘導すべきか Appleに通知します
「state」と「nonce」を追加して リクエストの安全性を確保することもできます
最後に「usePopup」 パラメータで ログイン画面を 別のポップアップ ウインドウで表示するか または 既存のウインドウで Appleサインインサイトに リダイレクトされます Safariを使用している場合 このようなネイティブ 画面が表示され Webサイトへの一流のサインイン体験を お届けします Apple IDサーバーが 認証リクエストを処理した後 認証結果を含む DOMイベントを受信します 成功のレスポンスを 処理するには "AppleIDSignInOnSuccess" のイベントリスナーを追加します
失敗のレスポンスを 処理するには "AppleIDSignInOnFailure" のイベントリスナーを追加します
認証に成功すると 認証コード IDトークン ユーザ情報が 含まれたレスポンスが 返されます ユーザー情報はリクエストされた場合のみ 返されます これは Appleのプラットフォームで すでに 慣れ親しんでいる レスポンスと同様です REST APIを使って Apple IDサーバと 直接連携したい場合 認証エンドポイントに 必要なパラメータを 指定して認証リクエストを 送信してください 認証に成功した場合 認証コード IDトークン およびユーザー情報を 含む応答が得られます すでに慣れ親しんでいる Appleプラットフォームでの 応答に非常に似ています 以上です Webサイトに Appleでサインインを導入できました 最後に Appleでサインインを 導入する際に 注意すべき点を いくつか挙げておきます
重要なアカウントベースの 機能を必要とする Appでない限り ログインを求めずに ユーザーに提供しましょう 例えば Apple Payで 商品を購入した後に オプションとして 購入した商品を アカウントに紐付けることを ユーザーに提案することが できます 既存のユーザーに対しては ユーザー名とパスワードでの 認証から Appleでサインインに切り替えて アカウントのセキュリティの アップグレードを提供しましょう ユーザーを特定するための 一意なIDが必要なら 名前もメールアドレスも 収集しないでください それでも Appleでサインインで メールアドレスを収集する場合 ユーザーの選択を 尊重してください 追加メールアドレスの催促は 行わないでください
AppやWebなど利用可能な すべてのプラットフォームで Appleでサインインを 実装することが重要です ユーザーは複数の プラットフォームを使用する 可能性があり どこにいても Appleでサインインを期待します Appleでサインインを使い どんなことができるのか 皆さんのフィードバックを お待ちしています ご視聴有難うございました WWDCの続きをお楽しみ下さい
-
-
4:03 - Presenting Existing Credentials
// Requesting both Sign in with Apple and password-based accounts. import AuthenticationServices let controller = ASAuthorizationController(authorizationRequests: [ ASAuthorizationAppleIDProvider().createRequest(), ASAuthorizationPasswordProvider().createRequest() ]) controller.delegate = self controller.presentationContextProvider = self if #available(iOS 16.0, *) { controller.performRequests(options: .preferImmediatelyAvailableCredentials) } else { controller.performRequests() }
-
5:14 - ASAuthorizationControllerDelegate Implementation
// ASAuthorizationControllerDelegate func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) { switch authorization.credential { case let appleIDCredential as ASAuthorizationAppleIDCredential: // Sign the user in with Apple ID credential. // ... case let passwordCredential as ASPasswordCredential: // Sign the user in with password credential // ... } } func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) { // No credential found. Fall back to login UI. }
-
12:00 - Checking Credential State
// Check User Credentials on app launch let appleIDProvider = ASAuthorizationAppleIDProvider() appleIDProvider.getCredentialState(forUserID: "currentUserIdentifier") { (credentialState, error) in switch(credentialState){ case .authorized: // Found valid Apple ID credential case .revoked: // Apple ID credential revoked. Log the user out. case .notFound: // No credential found. Show login UI. case .transferred: // Team is transferred } }
-
12:18 - Register for Revocation Notification
// Register for revocation notification let notificationName = ASAuthorizationAppleIDProvider.credentialRevokedNotification NotificationCenter.default.addObserver(self, selector: #selector(signOut(_:)), name: notificationName, object: nil)
-
17:55 - Sample HTML and Javascript Implementation
// Embed Sign in with Apple JS <html> <body> <script type="text/javascript" src="https://appleid.cdn-apple.com/appleauth/static/jsapi/appleid/1/en_US/appleid.auth.js"></script> <div id="appleid-signin" data-color="white" data-border="true" data-type="sign in"/> <script type="text/javascript"> AppleID.auth.init({ clientId : '[CLIENT_ID]', scope : '[SCOPES]', redirectURI : '[REDIRECT_URI]', state : '[STATE]', nonce : '[NONCE]', usePopup : true }); </script> </body> </html>
-
18:28 - White Sign in with Apple Button
<div id="appleid-signin" data-color="white" data-border="true" data-type="sign in"/>
-
18:38 - Black Sign in with Apple Button
<div id="appleid-signin" data-color="black" data-border="true" data-type="sign in"/>
-
18:44 - Black Continue with Apple Button
<div id="appleid-signin" data-color="black" data-border="true" data-type="continue"/>
-
18:50 - Black Logo Only Button
<div id="appleid-signin" data-color="black" data-border="true" data-mode="logo-only"/>
-
19:47 - Sample HTML and Javascript Implementation
// Embed Sign in with Apple JS <html> <body> <script type="text/javascript" src="https://appleid.cdn-apple.com/appleauth/static/jsapi/appleid/1/en_US/appleid.auth.js"></script> <div id="appleid-signin" data-color="white" data-border="true" data-type="sign in"/> <script type="text/javascript"> AppleID.auth.init({ clientId : '[CLIENT_ID]', scope : '[SCOPES]', redirectURI : '[REDIRECT_URI]', state : '[STATE]', nonce : '[NONCE]', usePopup : true }); </script> </body> </html>
-
21:11 - Handle DOM Response
// Listen for authorization success. document.addEventListener('AppleIDSignInOnSuccess', (event) => { // Handle successful response. console.log(event.detail.data); }); // Listen for authorization failures. document.addEventListener('AppleIDSignInOnFailure', (event) => { // Handle error. console.log(event.detail.error); });
-
-
特定のトピックをお探しの場合は、上にトピックを入力すると、関連するトピックにすばやく移動できます。
クエリの送信中にエラーが発生しました。インターネット接続を確認して、もう一度お試しください。