LoginSignup
37
34

More than 5 years have passed since last update.

アプリ内での Touch ID を利用したユーザ認証

Last updated at Posted at 2017-07-31

はじめに

  • モバイルデバイスにとって、認証は重要です(モバイルじゃなくてもだけど)
  • iOS デバイスには、 Touch ID という指紋認証機能が組み込まれています
  • Touch ID は、意外なほど簡単にアプリから利用できます

検証環境

  • Xcode 8.3.3
  • Swift 3.1
  • iOS 10.3

利用する機能

LocalAuthentication フレームワーク

LAContext クラス

  • このクラスを利用して、認証を行います
  • Touch ID 搭載されているデバイスでは Touch ID(または Passcode)を、搭載されていないデバイスでは Passcode で認証を行います
メソッド 説明
canEvaluatePolicy(_: error:) -> Bool Touch ID が搭載されていて有効な状態、または Passcode が設定されている状態(Touch ID がなくても)であれば true を返す。
evaluatePolicy(_: localizedReason: reply:) Touch ID または Passcode を利用した認証を実行する。認証結果に対する処理は、第3引数のコールバックとして指定する。

 LAPolicy 列挙型

  • 上記のメソッドに渡す定数が定義されています
  • iOS 9 以降であれば、後者の deviceOwnerAuthentication を利用します
定数 説明
deviceOwnerAuthenticationWithBiometrics iOS 8 で利用。 iOS 9 以降でこの定数を利用すると、フォールバックボタン(指紋が認証されなかった場合に Passcode 入力を促すボタン)を押しても、入力画面が出ない?1
deviceOwnerAuthentication iOS 9 以降で利用。

実装例

ViewController.swift
import UIKit
import LocalAuthentication

class ViewController: UIViewController {
    @IBOutlet weak var authResultLabel: UILabel!

    @IBAction func authenticate(_ sender: UIButton) {
        let myContext = LAContext()
        self.configure(context: myContext)
        let reason = "Only device owner can use this feature."

        var authError: NSError? = nil

        // Touch ID が有効または Passcode がセットされている状態であることを確認
        if myContext.canEvaluatePolicy(.deviceOwnerAuthentication, error: &authError) {
            // 認証を実行
            myContext.evaluatePolicy(.deviceOwnerAuthentication, localizedReason: reason) { (success, evaluateError) in
                if success {
                    print("Success")

                    DispatchQueue.main.async {
                        self.authResultLabel.text = "Success"
                    }
                } else {
                    let error = evaluateError! as NSError
                    let errorMessage = "\(error.code): \(error.localizedDescription)"

                    print(errorMessage)

                    DispatchQueue.main.async {
                        self.authResultLabel.text = errorMessage
                    }
                }
            }
        } else {
            // Touch ID と Passcode のいずれも有効ではない場合

            let errorMessage = "\(authError!.code): \(authError!.localizedDescription)"
            print(errorMessage)

            DispatchQueue.main.async {
                self.authResultLabel.text = errorMessage
            }
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    /// ボタンの文字列をカスタマイズ
    private func configure(context: LAContext) {
        context.localizedCancelTitle = "キャンセル"
        context.localizedFallbackTitle = "パスコードを入力"
    }
}

実行結果

初期状態(Authenticate ボタンを押すと、指紋認証を実行)

initial.png

指紋認証

touch_id.png

指紋認証失敗(パスコード入力を促すボタン表示)

try_again.png

パスコード入力

passcode.png

成功時

success.png

キャンセル時

cancelled.png

パスコードが設定されていない場合

no_passcode.png

サンプルプロジェクト

参考サイト



  1. Apple の公式ドキュメント上では、この挙動に関する記述が見つけられませんでした。ご存知の方がいらっしゃれば、ご指摘頂けるとうれしいです。また、手元に iOS 8 の載ったデバイスがなかったので、 iOS 8 での確認ができてません。 

37
34
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
37
34