こんにちは。Yahoo! ID連携のiOS SDKの開発・運用を担当している矢倉です。
現在、多くのヤフーのiOSアプリでは、ローカル認証を活用した独自のデバイス認証による再認証機能を搭載しています。この機能を提供しているのが、ヤフーのiOSアプリ向けのID連携 SDKです。
SDKでは、利便性とセキュリティを両立させるさまざまなログイン機能を提供していますが、このたび新たに同期パスキー(以下、パスキー)に対応しました。
パスキーを利用したログインの仕組みについては以下の記事で紹介されていますので、詳細は「FIDO認証&パスキー総復習(認証の仕組みやパスキー登場までの経緯)」をご覧ください。
以降、iOSアプリにおけるローカル認証を活用した独自のデバイス認証を標準規格であるパスキーへ移行した背景と、パスキー対応の内容を解説します。
移行した背景
ローカル認証を活用したデバイス認証
ヤフーのiOSアプリでは、2019年から Local Authentication framework(ローカル認証)を活用したログイン方法をサポートしてきました。
しかし、ヤフーのiOSアプリで扱うローカル認証によるログインは独自の仕様に基づいて実装されたものでした。
この記事では、ローカル認証だけでログインが完了するFIDOに近いデバイス認証方式のことを、 「独自仕様FIDO」 と呼びます。
この独自仕様FIDOには以下のようなデメリットがありました。
- 鍵を登録した端末でしか使えず、機種変更時などに鍵の再登録が必要
- ログイン状態でないと鍵が使えず、再認証にしか 利用できない
- ブラウザとアプリ間で鍵が共有されない
パスキー対応によるデメリット解消
独自仕様FIDOの課題を解決し、よりスムーズなユーザー体験を提供するためにパスキー対応を進めました。
パスキーを導入することで独自仕様FIDOのデメリットを解消できます。
- iCloudキーチェーンによるデバイス間同期
- パスキーはApple Account(旧Apple ID)にひも付くiCloudキーチェーンと連携します。これにより、作成したパスキーは同一Apple Account(旧Apple ID)でサインインしている端末間で同期されます
- 端末を変更・紛失した場合でも、鍵の再登録なしでパスキーによるログインが可能になります
- Webとの実装共通化
- iOS 16.4以降、アプリのWebView内でもWebAuthn APIが拡張され、認証フローが扱えるようになりました
パスキー対応の内容
パスキー実装方式の検討
iOSアプリでパスキーを実装するにあたり、ユーザー体験と開発コストのバランスを考慮し、どの方式が適切か比較検討を行いました。
iOSにおける同期パスキーの正式サポートはiOS 16から開始されていますが、アプリのWebView内で利用できるのはiOS 16.4以降となります。
まず、以下の3つの方式を候補として整理しました。
| 実装方式 | 実現方法 | 参考情報 |
|---|---|---|
| ネイティブAPI | ネイティブAPIによるPublic-Private Key認証 | Public-Private Key Authentication |
| SFSafariViewController / ASWebAuthenticationSession | ブラウザ相当のコンテキストでのWebAuthn API(JavaScript) | ASWebAuthenticationSession など |
| WebView(WKWebView) | アプリ内WebViewでのWebAuthn API(JavaScript) | iOS 16.4以降のWKWebViewでWebAuthnによるパスキーが利用可能 |
ネイティブAPI案
「ネイティブAPI」はOS標準のUIを利用でき、iOS 15以降で動作するというメリットがあります。一方で、ヤフーのiOSアプリでは既存のログイン画面がアプリ内WebView上にあり、Webベースのフローを前提とした実装になっています。
新規ログイン(※1)も含めてネイティブAPIに切り替える場合、以下のような課題がありました。
※1 アプリ内WebViewでログイン用のID入力画面が表示されるケース
- WebView上のID入力画面から、ネイティブの認証フローへ遷移させるための実装(ユニバーサルリンクなど)が必要
- Web側で構築済みのログインフローと、ネイティブ側の認証フローを連携する実装が複雑になる
- SDK利用アプリ側も、既存のWebViewベースのログイン連携からネイティブAPI連携へ切り替える必要があり、影響範囲が大きい
これらを踏まえると、既存のWebフローとネイティブAPIを連携させるための実装コストが高く、「ネイティブAPI」を採用するのは現実的ではないと判断しました。
SFSafariViewController / ASWebAuthenticationSession案
「SFSafariViewController / ASWebAuthenticationSession」を用いる案のメリットは、ブラウザ相当のコンテキストでWebAuthnを利用でき、iOS 15以降の幅広いOSバージョンで動作することです。
しかしこの案でも以下のようなデメリットが挙げられました。
- 既存のログイン画面がアプリ内WebView上にあるため、ログインUXを「SFSafariViewController / ASWebAuthenticationSession」側に移す必要がある
- それに伴い、
- 既存のWebViewベースのUXを見直す必要がある
- SDKが提供しているWebView連携インターフェースの設計を変更する必要がある
- iOS 15自体はサポートできるものの、iOS 15では同期パスキーには対応しておらず、デバイス固定パスキー用の追加開発が必要となる
- 古いOSバージョンのシェアに対して追加の開発コストが見合わない
OS対応範囲の広さというメリットはあるものの、既存UXやSDK連携部分への影響が大きいこと、開発コストに見合ったリターンが得られないことから採用を見送りました。
WebView案を採用した理由
最終的に、本SDKではWebView(WKWebView)を使う方式を採用しました。判断の主な理由は次のとおりです。
- 既存ログイン画面がWebView上にあり、SDK既存のWebViewロジックをそのまま流用できる
- Web側の資産(画面UI・認証ロジック)を活用できるため、ブラウザ向け実装との共通化がしやすい
- SDK利用アプリ側は従来どおりWebViewベースの連携を維持でき、アプリ側の改修量を抑えられる
- iOS 16.4以上であればWKWebViewからWebAuthn APIを呼び出すことでパスキーに対応できる
- iOS 16.4未満の端末についてはこれまでどおり既存の独自仕様FIDOでフォールバックできるため、OSバージョン間でのUXの差分を最小限に抑えられる
総合して検討した結果、本SDKでは「iOS 16.4以上はWKWebViewでパスキーに対応し、iOS 16.4未満は独自仕様FIDOを利用する」というハイブリッドな構成を採用しました。
この構成については後述する「独自仕様FIDOとパスキーの共存」で詳しく説明します。
iOSにおけるパスキー対応の実装
サーバー側がWebAuthnに対応済みであれば、アプリ側の対応は比較的シンプルです。
Supporting passkeys #Use passkeys in a web view を参考に設定を行うだけで、基本的な対応は完了します。
ここでは、apple-app-site-association に関する Tips を紹介します。
apple-app-site-associationの反映タイミング
apple-app-site-association はAppleのCDNを経由して取得されます。
そのため、Supporting associated domains に記載のとおり、実際にアプリに設定が反映されるまでは最長1週間ほどかかります。全アプリに対して即時反映させる機能はないため注意が必要です。
なお、CDN の更新頻度やアプリ側への反映タイミングなどの挙動は将来的に変更される可能性があります。最新の仕様については必ず公式ドキュメントを確認してください。
- Apple CDN
- 24時間以内に1回更新
- アプリ(CDNから取得)
- インストール・再インストール時 に新規取得
- インストール後、約1週間に1回更新
開発時は mode=developer を付与することで、Apple CDNを経由せずに直接 apple-app-site-association を取得できます。反映の制限がなくなるため便利です。
<string>webcredentials:*.yahoo.co.jp?mode=developer</string>
独自仕様FIDOとパスキーの共存
独自仕様FIDOを利用中のすべてのユーザーが即座にパスキーへ移行できるわけではありません。また、iOS 16.4未満の端末を利用しているユーザーも多数存在します。
ユーザー体験を損なわないよう、再認証時には独自仕様FIDOとパスキーを共存させ、パスワードレスログインがこれまでどおりできる仕組みが必要でした。
今回はサーバー側とWeb側がWebAuthnに対応済みだったため、以下の機能が主な実装対象になります。
- 利用可能な認証方式に合わせ、独自仕様FIDOとパスキーのどちらかを発動させる
- パスキーが利用できない端末の場合は独自仕様FIDOを発動させる
- 独自仕様FIDOを利用しているユーザーに対してパスキーの登録を促す
SDKでは表のようにOSや登録状況に応じて認証方式を出し分けています。
| OSバージョン | 鍵登録 | 再認証 |
|---|---|---|
| iOS 16.4未満 | 独自仕様FIDO | 独自仕様FIDO |
| iOS 16.4以上 | 同期パスキー | 独自仕様FIDO または 同期パスキー |