UnityでiOS向けのSing in with Appleを実装し、FirebaseAuthと連携していく方法を解説します。
とても簡単です。
前提として、「Firebaseにアプリのプロジェクトを作成」し、かつ、「iOSの開発ライセンスも取得済み」とします。
Android向けのSign in with Appleはコチラの記事を参照してみてください。
Googleログインの実装はコチラの記事を参照してみてください。
XCodeでSign in With Appleの有効化
UnityでiOSビルドをし、iOSプロジェクトをXCodeで開きます。
TARGETSからアプリを選択して、Signing & Capabilitiesタブを選択して、+ Capabilityボタンを押す。
リストからSign in with Appleを選択。
これでプロジェクトにSign in with Appleが有効になります。
FirebaseでSign In With Appleの有効化
Firebaseで該当プロジェクトを開き、Authenticationメニューで、Sign-in methodタブを選び、新しいプロバイダを追加ボタンを押し、Apple認証を追加します。
iOSの場合、有効化するだけで、各種オプションの入力は不要です。
実装
FirebaseAuthパッケージの導入
以下のリンクから最新版のFirebase Unity SDKをダウンロードします。
今回はバージョン11.2.0を導入しています。
既に他のFirebaseパッケージを導入済の場合は同じバージョンのFirebaseAuthパッケージを入れるか、最新のパッケージを全て入れ直してください。
そうしないとエラーで動きません。
ダウンロードしたら解凍して、FirebaseAuth.unitypackage をimportします。
Sign in with Appleパッケージの導入
次に非公式Sign in with Appleパッケージをimportします。
C#の実装
後は実装するだけです。
詳細はソースのコメントを参照してください。
using UnityEngine;
using Firebase.Auth;
using Firebase.Extensions;
using System.Runtime.InteropServices;
using System;
using System.Collections.Generic;
using AppleAuth.Interfaces;
using AppleAuth;
using AppleAuth.Native;
using AppleAuth.Enums;
using System.Threading.Tasks;
using System.Security.Cryptography;
using System.Text;
public class TestController : MonoBehaviour
{
private FirebaseAuth auth;
Firebase.DependencyStatus dependencyStatus = Firebase.DependencyStatus.UnavailableOther;
private AppleAuthManager appleAuthManager;
private void Start()
{
// FirebaseAuthの初期化
Firebase.FirebaseApp.CheckAndFixDependenciesAsync().ContinueWithOnMainThread(task =>
{
dependencyStatus = task.Result;
if (dependencyStatus == Firebase.DependencyStatus.Available)
{
auth = FirebaseAuth.DefaultInstance;
}
else
{
Debug.Log($"error: {dependencyStatus}");
}
});
}
private void Update()
{
// これやらないとSign In後の処理が進まない
if (this.appleAuthManager != null)
{
this.appleAuthManager.Update();
}
}
public void SignInWithAppleForiOS()
{
var deserializer = new PayloadDeserializer();
this.appleAuthManager = new AppleAuthManager(deserializer);
// 暗号化した文字列(nonce)を渡して認証し、認証結果に暗号化前の文字列を渡して改ざんチェックをする
var rawNonce = GenerateRandomString(32);
var nonce = GenerateSHA256NonceFromRawNonce(rawNonce);
var loginArgs = new AppleAuthLoginArgs(LoginOptions.IncludeEmail | LoginOptions.IncludeFullName, nonce);
appleAuthManager.LoginWithAppleId(
loginArgs,
credential =>
{
var appleIdCredential = credential as IAppleIDCredential;
if (appleIdCredential != null)
{
// Sign In成功!
var identityToken = Encoding.UTF8.GetString(appleIdCredential.IdentityToken);
var authorizationCode = Encoding.UTF8.GetString(appleIdCredential.AuthorizationCode);
Credential credencial = OAuthProvider.GetCredential("apple.com", identityToken, rawNonce, authorizationCode);
var signInCompleted = new TaskCompletionSource<FirebaseUser>();
// AppleアカウントをFirebaseAuthに紐付ける
auth.SignInWithCredentialAsync(credencial).ContinueWith(task =>
{
if (task.IsCanceled)
{
Debug.Log($"canceled");
signInCompleted.SetCanceled();
}
else if (task.IsFaulted)
{
Debug.Log($"fault {task.Exception}");
signInCompleted.SetException(task.Exception);
}
else
{
Debug.Log($"complete!");
signInCompleted.SetResult(task.Result);
}
});
} else
{
Debug.Log($"no credential!");
}
},
error =>
{
Debug.Log($"sign in error");
});
}
private static string GenerateRandomString(int length)
{
if (length <= 0)
{
throw new Exception("Expected nonce to have positive length");
}
const string charset = "0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._";
var cryptographicallySecureRandomNumberGenerator = new RNGCryptoServiceProvider();
var result = string.Empty;
var remainingLength = length;
var randomNumberHolder = new byte;
while (remainingLength > 0)
{
var randomNumbers = new List<int>(16);
for (var randomNumberCount = 0; randomNumberCount < 16; randomNumberCount++)
{
cryptographicallySecureRandomNumberGenerator.GetBytes(randomNumberHolder);
randomNumbers.Add(randomNumberHolder[0]);
}
for (var randomNumberIndex = 0; randomNumberIndex < randomNumbers.Count; randomNumberIndex++)
{
if (remainingLength == 0)
{
break;
}
var randomNumber = randomNumbers[randomNumberIndex];
if (randomNumber < charset.Length)
{
result += charset[randomNumber];
remainingLength--;
}
}
}
return result;
}
private static string GenerateSHA256NonceFromRawNonce(string rawNonce)
{
var sha = new SHA256Managed();
var utf8RawNonce = Encoding.UTF8.GetBytes(rawNonce);
var hash = sha.ComputeHash(utf8RawNonce);
var result = string.Empty;
for (var i = 0; i < hash.Length; i++)
{
result += hash[i].ToString("x2");
}
return result;
}
}
Sign in with Appleが成功し、FirebaseAuthとの連携が成功すると、FirebaseにAppleと連携したアカウントが作成されます。