SignInWithAppleに対応する
SignInWithAppleとは
2019年のWWDCで発表されたAppleが開発した新しい認証方法です。
新規のアプリ申請では対応必須となっており、アップデート申請も7月から対応必須となります。
対応しない場合はリジェクト対象となりますので忘れずに対応しましょう。
準備編
AppleDeveloperでの設定
AppleDeveloperのサイトにアクセスして以下の設定をします。
Certificates, Identifiers & Profiles→Identifiers→対象のアプリ→CapabilitiesからSigninWithAppleにチェック
Xcodeの設定
次にXcodeのCapabilitiesにSignInWithAppleを追加します。
手順は以下です。
TARGET→Signing&Capabilities→Capabilityを選択してSigninWithAppleを追加
実装編
Nonceを取得する
APIでNonceを取得するAPIを叩くか以下の関数を実装してNonceを取得します。
(https://firebase.google.com/docs/auth/ios/appleより引用)
func randomNonceString(length: Int = 32) -> Observable<String> {
precondition(length > 0)
let charset: Array<Character> = Array("0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._")
var result = ""
var remainingLength = length
while remainingLength > 0 {
let randoms: [UInt8] = (0 ..< 16).map { _ in
var random: UInt8 = 0
let errorCode = SecRandomCopyBytes(kSecRandomDefault, 1, &random)
if errorCode != errSecSuccess {
fatalError("Unable to generate nonce. SecRandomCopyBytes failed with OSStatus \(errorCode)")
}
return random
}
randoms.forEach { random in
if length == 0 {
return
}
if random < charset.count {
result.append(charset[Int(random)])
remainingLength -= 1
}
}
}
return .just(sha256(result))
}
func sha256(_ input: String) -> String {
let inputData = Data(input.utf8)
let hashedData = SHA256.hash(data: inputData)
let hashString = hashedData.compactMap {
return String(format: "%02x", $0)
}.joined()
return hashString
}
ViewControllerの実装
ボタンイベント等で以下の処理を実装して認証画面を表示します。
let provider = ASAuthorizationAppleIDProvider()
let request = provider.createRequest()
request.requestedScopes = [.email, .fullName]
request.nonce = nonce
let controller = ASAuthorizationController(authorizationRequests: [request])
controller.delegate = self
controller.presentationContextProvider = self
controller.performRequests()
認証の実装
ログイン画面のViewControllerにASAuthorizationControllerDelegate
とASAuthorizationControllerPresentationContextProviding
を実装します。
func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
// 認証成功時の処理
}
func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) {
// 認証失敗時の処理
}
func presentationAnchor(for controller: ASAuthorizationController) -> ASPresentationAnchor {
// コンテンツを表示するWindowを指定
// UIViewControllerのwindowを指定する
return self.view.window!
}
状態監視の実装
AppDelegateのapplicationDidBecomeActive
関数で以下のチェック処理を実装します。
let provider = ASAuthorizationAppleIDProvider()
provider.getCredentialState(forUserID: appleId) { state, error in
switch state {
// 認証が無効になった場合
case .revoked, .notFound:
// サービスのログアウト処理
default:
break
}
}
}
実装してみた感想
今回初めて実装してみましたがかなり簡単に実装できて実装もシンプルなのでかなり良い印象でした。
ただ公式ドキュメントが少しわかりにくいのでそのへん改善して欲しいなと思いました。
参考サイト
全く知らない人のためのSign in with Apple
Discussion