[Xcode/Swift] Sign in with Appleを理解してみる① 🍎

1. はじめに

1.1 「Sign in with Apple」とは?

Sign in with Apple(Appleでサインイン)= Apple ID を使ってアプリやWebサービスにログインできる仕組み

  • 「Appleでサインイン」ボタンをタップ
  • Face ID / Touch ID / パスコードで認証
  • アプリ側に「この人はこのApple IDユーザーですよ」という情報が渡る

という流れで、ユーザーは新しいパスワードを覚えなくて済むようになるので便利。

技術的には、

  • OAuth 2.0
  • OpenID Connect(IDトークン:JWT)

といった仕組みをベースにした、Apple公式のログイン手段だそう。


1.2 「Appleでサインイン」を導入するメリット

① UX(ユーザー体験)が段違いに良くなる

  • 新規登録フォームで
    • 名前
    • メールアドレス
    • パスワード
      • これらを入力させる必要がない
  • ワンタップ+Face IDでサクッとログイン完了

離脱率の低下 & 会員登録率アップに期待できる。

② プライバシー重視のユーザーに好まれる

  • メールアドレスを「隠す(非公開メール)」という選択肢がある (詳細は以降に)
  • 追跡やプロフィール収集に敏感なユーザーでも、「Appleなら使ってもいいか」となりやすい

③ Appleのガイドライン的にも重要

  • 他社のログイン(Facebook / Google / Twitter 等)を入れる場合、
    一緒に「Appleでサインイン」も提供することが求められるケースがあります
  • 将来的なリジェクトリスクを減らす意味でも、早めに理解&導入しておく価値はアリ

1.3 本記事のゴールと前提知識

このシリーズ記事では、

  • 「Sign in with Apple」の仕組みをざっくり理解
  • UIKit / SwiftUI それぞれでの基本的な実装方法
  • 実務でよく出るハマりどころ・設計の考え方

このあたりを、初心者〜中級者向けにやさしく解説していきます。

この記事を読み終えるころには、

  • 「Sign in with Apple」がどういう流れで動いているか
  • なぜIDトークンAuthorizationCodeが出てくるのか
  • 「メールを隠す」って具体的に何をしているのか

といったところが、頭の中でスッキリ整理されている状態を目指します。

想定する前提レベル:

  • Swift / Xcode で簡単なアプリを作ったことがある
  • UIKit または SwiftUI どちらか/両方に軽く触れたことがある
  • ネットワークやサーバーの知識は薄くてもOK(サーバー連携は“概要”レベルで説明)

2. Sign in with Apple の仕組みを理解する

ここではコードを書く前に、まずはざっくりと頭で概要をイメージできることを目標にしましょう。

2.1 認証フローの全体像(クライアント〜Appleサーバ〜自サーバ)

ざっくりとフローをまとめるとこんな感じ:

[ユーザー]
    ↓ (ボタンをタップ)
[iOSアプリ]
    ↓ (認証リクエスト)
[Appleの認証UI / Appleサーバ]
    ↓ (許可)
[iOSアプリ]
    ↓ (IDトークン / AuthorizationCode)
[自分のサーバ](任意)

もう少し噛み砕いて解説すると:

  1. ユーザーがアプリで「Appleでサインイン」ボタンをタップ
  2. iOSがAppleの認証UIを表示
    • Face ID / Touch ID / Apple IDのパスワードなどで本人確認
    • 初回だけ「名前・メールをこのアプリに渡してよいか?」という確認が出る
  3. 認証に成功すると、アプリに対して「認証情報」が返ってくる
    • user(Appleが発行するユーザーID)
    • identityToken(IDトークン:JWT)
    • authorizationCode(後でサーバーがトークン交換に使うコード)
    • 初回のみ fullName, email が入ることもある
  4. アプリは、必要に応じてそれを自分のサーバーに送る
    • サーバー側で「本当にAppleが発行したトークンか?」を検証
    • 自サービスのユーザーとして登録 / ログイン処理を行う

ポイントは、「誰を信用するか?

  • クライアント(iOSアプリ)は、改ざんされる可能性がある
  • サーバー(バックエンド)は、自分たちがコントロールできる安全な場所
  • Appleは「この人はこのApple IDで認証したよ」という事実を保証する存在

なので、
本当にしっかりやる場合は「サーバー側でトークン検証する」のが基本、
とはいえ個人開発や小規模アプリでは「まずはクライアント側だけで運用する」というパターンで大体OK(このあたりは後のセクションで触れます)。


2.2 Apple ID・IDトークン(JWT)・AuthorizationCodeとは

よく出てくる用語を一旦整理しておきましょう。

■ Apple ID

ユーザーが普段使っている、Appleアカウントそのもの。

  • iCloud
  • App Store
  • Apple Music

などにログインするときに使っているID。

アプリ側はApple IDの生の情報を直接扱わず、代わりに、アプリごとにユニークな識別子(user)が付与される。


■ user(ユーザー識別子)

Sign in with Appleで認証した際に、ASAuthorizationAppleIDCredentialuser プロパティとして返ってくる文字列。

  • 同じアプリ・同じApple IDなら 同じ user が返る
  • 別アプリだと 別の user が返る(追跡防止のため)
  • 自分のデータベースの「ユーザーID」として保存しておくのがベター
例)Usersテーブル
-----------------------------
id (auto) | apple_user_id | ...
1         | 000123.abcd...| ...

■ IDトークン(JWT)

identityToken として返ってくるデータで、
中身は JWT(JSON Web Token) という形式の文字列。

「このユーザーはこのApple IDで、いつ認証されたか」などをAppleが署名付きで証明している電子的な「証明書」のようなもの

この認識でOK。

JWT は . で3つに区切られた文字列:

xxxxx.yyyyy.zzzzz
ヘッダ. ペイロード. 署名

ペイロード部分(yyyyy)には、

  • ユーザー識別子(sub
  • 発行日時(iat
  • 有効期限(exp
  • イシュー(iss:Apple)
  • 受け取り側(aud:あなたのAppのID)

などの情報が入ってる。

※ 中身を確認するときは、本番データではなく Sandbox などで実験するのがベター。


■ Authorization Code(認可コード)

authorizationCode として返ってくるデータ。

これは主に サーバーサイド用 で、

  1. アプリ → サーバーに authorizationCode を送る
  2. サーバー → Appleのエンドポイントに authorizationCode を渡す
  3. Apple → サーバーに対してアクセストークンなどを返す

という「トークン交換」のために使われるもの。

クライアントだけでやるシンプル実装では、深追いしなくてもOKだけど、
サーバー側でしっかりユーザーを管理する場合は必須の概念になります。


2.3 メールリレー(非公開メール)の仕組み

Sign in with Apple の目玉機能のひとつが、
ユーザーの本物のメールアドレスを隠しつつ、メールを届けられる仕組み

ユーザーが初回ログイン時に、

  • メールアドレスを共有する
  • メールアドレスを隠す(非公開)

のどちらかを選べることができて、
「隠す」を選んだ場合、開発者側にはこんな感じのメールアドレスが渡される:

abc123xyz@privaterelay.appleid.com

これがいわゆる リレー用メールアドレス

特徴:

  • このアドレスにメールを送ると、Apple側がユーザーの本物のメールアドレスに転送してくれる
  • アプリごとにユニーク(他のアプリとは共有されない)
  • ユーザーがAppleアカウント設定から「このアプリとの連携を解除」すると、リレーが無効になる可能性がある(= 届かなくなる)

開発者視点:

  • データベース上には本物のメールアドレス」ではなく「リレーアドレス」が保存される
  • 通常のメールアドレスと同じように送信してOK(Appleが裏で転送してくれる)

2.4 プライバシーとセキュリティのポイント

Sign in with Apple の設計思想は 「最小限の情報だけを共有する」 こと。

開発者が手に入るユーザー情報は、基本的にはかなり絞られる:

  • 必ず得られるもの
    • user(アプリ固有のユーザー識別子)
  • 初回ログイン時のみ、条件付きで得られるもの
    • 名前(fullName
    • メールアドレス(本物 or リレーアドレス)

2回目以降のログインでは、名前やメールアドレスは返ってこないことが多いので、

  • 「最初の1回でちゃんと保存する」
  • 「いつでも取り直せる」と思わない

という設計が重要になるという認識を持てればここではOK。

セキュリティ面で意識すること:

  • IDトークン(JWT)の署名を検証するのは本来サーバー側の役割
  • クライアント側だけを信用して「このトークンがあるからOK!」とするのは、厳密には危険
  • とはいえ、小さなアプリやプロトタイプでは、まずクライアントのみで始めて、大きくなったタイミングでサーバーを整える、というロードマップでOK

ここまでで、

  • 「Sign in with Apple」がどんな登場人物で構成されているか
  • アプリ / Apple / 自サーバーがどう役割分担しているか
  • メールリレーやIDトークンのざっくりしたイメージ

が掴めていればOK。

次のセクションでは、Sign in with Appleをプロジェクトで使用するための事前準備をざっくりと解説します。


導入前の準備

3.1 必要要件(対応OSバージョン・Xcode・Apple Developer Program)

まず、「Sign in with Apple」がそもそも動く条件を軽く整理しておきます。

対応OSバージョン

  • iOS 13 以降
    • Sign in with Apple は iOS 13 から登場した機能なので、アプリの Deployment Target を 13.0 以上にしておくのが基本です。(今はさすがにそんなに古いVerで運用することはない気がしますが)

実務では、多くのアプリがすでに iOS 14〜15 以上に切り上げているので、
「Sign in with Apple のために OS バージョンを上げる」というよりは、
“最近の標準的なターゲットにしておけば自然と対応している” くらいのイメージでOK。

Xcode

  • できるだけ新しい Xcode を使っておけばOK
    • 目安としては「最新もしくは1個前くらい」のバージョンを使うイメージ。

古い Xcode だと、

  • Sign in with Apple 用のボタンが出てこない
  • Capability の一覧に「Sign in with Apple」がない

などのハマりがあるので、基本は最新にしておくのがおすすめ。

Apple Developer Program(有料アカウント)

ここが少しややこしいポイントですが、ざっくりまとめると:

  • 無料の Apple ID だけ
    • シミュレータ実行や、ある程度までの実機テストはできる
    • ただし、本格的な「App ID の設定」「配布」「本番運用」は限界あり
  • Apple Developer Program(年額・有料)
    • Beta配信、App Store配信が可能
    • 各種 Capability(プッシュ通知・Sign in with Apple など)の本番運用
    • 複数端末でのテスト・TestFlight …などが正式に使える

この記事では、
「本番でちゃんと Sign in with Apple を動かすには、有料の開発者アカウントが必要」
という前提で話を進めますが、

今はまだ有料アカウントを持っていない

との場合、まずは

  • 「Developerサイトではこんな設定をするんだな」
  • 「Xcode ではこういうCapabilityを有効にするんだな」

という “地図レベルの理解” を目標に読んでもらえればOK。


3.2 Apple Developer サイトでの設定(ざっくり)

Sign in with Apple を使うためには、
Apple側に「このアプリは Sign in with Apple を使います」と宣言する必要があります。

そのために、Developerサイトでは主にこの2つの対応が必要:

  • App ID(Identifier)の作成・確認
  • その App ID に対して 「Sign in with Apple」を有効化

3.2.1 App ID / Identifier の設定

Developerサイトの「Certificates, Identifiers & Profiles」あたりで行う作業。
流れだけざっくり書くと:

  1. アプリの識別子(Bundle ID)を決める
    • 例:com.example.MyCoolApp
  2. その Bundle ID に対応する App ID(Identifier)を作る
    • 説明(Description):画面一覧などに出るアプリ名っぽい文字列
    • Bundle ID:上で決めた com.example.〜 を設定
  3. App ID を作成するときに、
    「どんな機能を使うアプリか?」をチェックボックスで指定する欄があります
    → この中にある 「Sign in with Apple」 をオンにする

イメージとしては、

「このアプリ(Bundle ID)は、Sign in with Apple を使う権利がありますよ」

と Apple に登録しているイメージ。


3.2.2 Sign in with Apple の有効化(コンセプトだけ)

Sign in with Apple は、
「どのアプリ(+どのWebサービス)を同じログイングループにするか」
という考え方があります。

ただ、この記事の想定は:

  • ネイティブ iOS アプリ単体
  • Web連携や他プラットフォームとの統合は一旦考えない

なので、今はシンプルに、

  • 作成した iOS 用 App ID に対して
  • 「Sign in with Apple」サービスを有効にする

くらいのイメージでOK。

Webや他プラットフォームとアカウントを共通化したい場合は、

  • 同じ「Sign in with Apple グループ」に紐づける
  • Web用の Services ID を追加で設定する

といった設計の話が出てきますが、
それは一段レベルアップしたときに触れればOK。


3.3 Xcode プロジェクトでの設定


Developerサイトで

App ID を作ってSign in with Apple を有効化する

という準備ができたら、
次は Xcode プロジェクト側で「このアプリはその権利を使います」と宣言する 作業が必要。


3.3.1 Capability の追加

Xcode 上での大まかな流れはこんな感じ:

  1. Xcode でプロジェクトを開く
  2. 左のナビゲータで アプリのターゲット を選択
  3. 上部タブから 「Signing & Capabilities」 を選ぶ
  4. 左上あたりにある 「+ Capability」 ボタンを押す
  5. 一覧から 「Sign in with Apple」 を選択

これを追加すると、Xcodeが裏側で

  • .entitlements ファイルに必要な権限を追加
  • プロジェクト設定に適切なフラグを立てる

などを自動でやってくれます。


3.3.2 Signing & Capabilities の確認ポイント

最後に、Xcode 上でざっくりチェックしておきたいのはこのあたり:

  • Team が自分のApple ID(もしくは Developer Program のチーム)になっているか
    • Signing & Capabilities > Team のところ
  • Bundle Identifier が、Developerサイトで作った App ID と一致しているか
    • ここが違うと、Developer側で設定した「Sign in with Apple」の権限が噛み合わない
  • 「Sign in with Apple」Capability のところに
    明らかなエラー(赤いマークなど)が出ていないか

有料アカウントがない場合、
実際にここまで設定してビルドするところまでは行けないかもしれませんが、

  • Developerサイト:App IDと機能の宣言
  • Xcode:その機能を実際のアプリに紐づける

という 役割の違い がイメージできていればOK。

次は、実際に実装を行い、
UIKit 版(4. UIKitでの Sign in with Apple 実装)SwiftUI 版(5. SwiftUIでの実装) をざっくりと学んでいきましょう。

↓ 続く

[Xcode/Swift] Sign in with Appleを理解してみる② 🍎