embryo

エンジニアの備忘録

UniversalLinksの挙動について

OpenIDConnectのクライアント実装のためにUniversalLinksを使用したので、その挙動についてまとめました。

Webブラウザからアプリへの遷移方法

AppScheme

app://[*] でアプリへのリンクを実現しようというもの。被ったり敢えて被せてくるセキュリティリスクがあるため、iOS9以降では非推奨になっています。

UniversalLinks

アプリ起動のためのよりセキュアな仕様。詳しくは下記参照。

App Search Programming Guide: Support Universal Links

webサイトのURLとアプリケーションを紐付けるため名前被りの心配が不要になる他、関連付けをwebサーバーに問い合わせる必要があるためよりセキュアになります。

実装

1. apple-app-site-association をwebサーバーに設置する

appIDにはTeamIDBundle Identifierをつなぎ合わせたものを指定します。pathsには設定したいパスを設定します。特に指定しない場合は*を指定します。

"applinks": {
  "apps": [],
  "details": [
    {
      "appID": <TeamID>.<Bundle Identifier>,
      "paths": ["/path/to/website"]
    }
  ]
}

https配信に対応している場合は上記のファイルを設置するだけで完了です。(2の手順は必要ありません)

2. SSL証明書で署名する

1.で作成したファイルをhandoff.jsonとして保存し、キーチェーンアクセスから、iPhone Distribution 用の SSL証明書を書き出します(certificate.p12)。

証明書から秘密鍵を書き出します。

openssl pkcs12 -in certificate.p12 -out certificate.key -nocerts

証明書から公開鍵を書き出します。

openssl pkcs12 -in certificate.p12 -out certificate.pem -nodes -clcerts -nokeys

handoff.json を署名します。

cat handoff.json | openssl smime -sign -inkey certificate.key -signer certificate.pem -certfile certificate.pem -noattr -nodetach -outform DER > apple-app-site-association

ここで出力したファイルをwebサーバーに設置すれば完了です。

3. アプリ側の設定

CapabilitiesでAssociated Domainsを有効(ON)にし、以下の値で設定します。 applinks:準備したwebサーバーのドメイン

4. アプリ側の処理

application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Void) -> Bool を用いてアプリケーション側のハンドリングを追加します。 SearchAPI や Handoff にも反応してしまうため、activityTypeでフィルタリングする必要があります。

    func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Void) -> Bool {

        // Universal linksを処理します
        if userActivity.activityType == NSUserActivityTypeBrowsingWeb {
            // handle universal links
        }

        return true

    }

OpenIDConnectを実現する上での注意点

基本的にユーザー操作に起因しての遷移以外ではUniversalLinksによるアプリ起動は行われない仕様になっているため、状況に応じて以下のような対応が必要になります。(※iOS-Safariのアップデートによって挙動が変わる可能性があります。)

リソースプロバイダ側で認可前の場合

  • リソースプロバイダ側で入力必須であり、ログインボタンを明示的に押下する必要があるので問題なし
  • redirect_url先でUniversalLinksのURLにリダイレクトしても問題なし

リソースプロバイダ側で認可済みの場合

  • リソースプロバイダ側で「アプリに戻る」ボタンを設置
  • もしくはUniversalLinks対象の画面に「アプリに戻る」ボタンを設置

ちなみにfacebookなども認可済みの場合は「アプリに戻る」ボタンを設置しています。

その他

apple-app-site-association の設置状況や内容が正しい状態になっているかの確認は下記チェッカーを使用しました。うまくいかない場合はこちらで確認してみると便利です。

Universal Link Validator

参考