【Swift】LocalAuthenticationでTouch IDやFace IDでの認証機能を実装する方法!

この記事からわかること

  • SwiftLocalAuthenticationフレームワークとは
  • iOSアプリ生体認証実装する方法
  • Touch IDFace ID認証する方法
  • LAContextクラス使い方
  • canEvaluatePolicyevaluatePolicyの使い方

index

[open]

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

環境

Touch IDやFace IDでの認証機能

Apple製品のデバイスに備わっているTouch IDやFace IDを使用した生体認証機能はロックを解除する際だけでなく、アプリのインストール時の認証や購入時などこれまでパスワードを入力していた場面に置き換わり使用者としても欠かせない機能の1つになっています。

iOSアプリを開発する際もアプリにロックをかける場合がある場合があり、その際にTouch IDやFace IDを使用した認証機能を導入してみたので実装方法や注意点などをまとめていきます。

【Swift】LocalAuthenticationでTouch IDやFace IDでの認証機能を実装する方法!

Apple製品の生体認証はSecure Enclave(セキュアエンクレーブ)と呼ばれるセキュリティプロセッサによって管理されています。このSecure EnclaveはOSからもアクセスできない場所でデータを管理しているため強固なセキュリティを実現しているようです。Swiftでも実際のデータ自体にアクセスはできませんがLocalAuthenticationというフレームワークが仲介として様々な機能を提供してくれています。

公式リファレンス:Secure Enclave

LocalAuthenticationフレームワーク

公式リファレンス:LocalAuthentication Framework

SwiftでTouch IDやFace IDを使用した認証機能を実装するためにはLocalAuthenticationフレームワークを使用します。このフレームワークでは生体認証(Touch IDやFace ID)、登録済みのパスフレーズ(パスワード)で認証をできるAPIを提供しています。このフレームワークではセキュリティ面が考慮され、認証機能の基盤である指紋情報や顔情報などにはアクセスできないようになっています。

公式サイトに実装サンプルが用意されていたのでこれを元に実装していきたいと思います。

公式リファレンス:Logging a User into Your App with Face ID or Touch ID

実装方法

実装の手順

  1. NSFaceIDUsageDescriptionキーの追加
  2. 生体認証管理クラスを作成

NSFaceIDUsageDescriptionキーの追加

アプリから生体認証機能を利用するためには「info.plist」にキーを追加し使用する理由を明記する必要があります。

生体認証管理クラスを作成

アプリ内で利用しやすいように生体認証管理クラスを作成していきます。生体認証を利用するために重要になるのがLAContextクラスです。詳細は後述しますがこのクラスから生体認証に関する処理を呼び出していきます。完成したコードは以下の通りです。


class BiometricAuthManager: ObservableObject {
    
    @Published  private(set) var isLogin = false
    private var context: LAContext = LAContext()
    
    /// 生体認証でログイン処理をリクエスト
    public func requestBiometrics() {
        // コンテキストは都度リセットしないと何度も認証なしでログインできてしまう
        context = LAContext()
        
        var error: NSError?
        // 生体認証を利用可能かどうか識別
        guard context.canEvaluatePolicy(.deviceOwnerAuthentication, error: &error) else {
            print(error?.localizedDescription ?? "生体認証をサポートしていないデバイスです")
            return
        }
        
        // キャンセルボタンの文言を指定
        context.localizedCancelTitle = "キャンセル"
        
        Task {
            do {
                // ユーザーに生体認証をリクエスト
                try await context.evaluatePolicy(.deviceOwnerAuthentication, localizedReason: "生体認証を利用してアプリにログインできます。")
                isLogin = true
            } catch {
                print(error.localizedDescription)
            }
        }
    }
    
    /// ログアウト
    public func logout() {
        isLogin = false
    }
}

UI部分は以下のように実装できます。


struct ContentView: View {
    
    @StateObject  private var biometricAuthManager = BiometricAuthManager()
    
    var body: some View {
        VStack {
            Text(biometricAuthManager.isLogin ? "ログイン中" : "ログアウト中")
            
            Button {
                if biometricAuthManager.isLogin {
                    biometricAuthManager.logout()
                } else {
                    biometricAuthManager.requestBiometrics()
                }
            } label: {
                Text(biometricAuthManager.isLogin ? "ログアウト" : "認証する")
            }
        }
        .padding()
    }
}

シミュレーターでも動作確認自体は可能ですが指紋や顔認証はできないので以下のようなパスワードを求められるだけになります。

【Swift】LocalAuthenticationでTouch IDやFace IDでの認証機能を実装する方法!

LAContextクラス

公式リファレンス:LAContextクラス

LAContextクラスは生体認証などSecure Enclaveへのインターフェイスとして機能するクラスで、アプリから指定した認証ポリシーを評価(アクセスや認証の可否)しています。

canEvaluatePolicyメソッド

func canEvaluatePolicy(
    _ policy: LAPolicy,
    error: NSErrorPointer
) -> Bool

canEvaluatePolicy指定した認証ポリシーが利用可能かどうかを識別するためのメソッドです。引数にはLAPolicy型で認証ポリシーの種類を指定します。たとえばデバイスの設定でTouch IDが無効になっている場合、生体認証を必要とするポリシーは認証できません。

evaluatePolicyメソッド

func evaluatePolicy(
    _ policy: LAPolicy,
    localizedReason: String) async throws -> Bool

evaluatePolicy指定されたポリシーを非同期的に評価するためのメソッドです。2つ目の引数localizedReasonには認証ダイアログに表示するメッセージを渡します。

【Swift】LocalAuthenticationでTouch IDやFace IDでの認証機能を実装する方法!

引数違いでcompletionHandlerから結果を取得できるメソッドも用意されています。

context.evaluatePolicy(.deviceOwnerAuthentication, localizedReason: "生体認証を利用してアプリにログインできます。") { [weak self] result, error in
    guard let self = self else { return }
    if let error = error  {
        print(error.localizedDescription)
        return
    }
    self.isLogin = result
}

サポートしている生体認証を識別する

デバイスがサポートしている生体認証を識別するためにはLAContextbiometryTypeプロパティから参照することができます。取得するためにはcanEvaluatePolicyを実行した後のLAContextでないとサポートしている生体認証を識別できていないので注意してください。

// canEvaluatePolicyを実行
switch context.biometryType {
  case .none:
      print("生体認証が使用できない")
  case .faceID:
      print("faceIDをサポート")
  case .touchID:
      print("touchIDをサポート")
  case .opticID:
      print("opticIDをサポート")
  @unknown  default:
      print("不明")
}

※opticIDはApple Vision Proのロックを解除するための虹彩認証

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index