Unity:Firebase接入Apple登录
此文章只是粗浅之作,记录而已,有错望指出,不胜感激
开启Firebase的登录方式
进入Firebase控制台==> 登录方式, 将Apple的登录方式开启,如果只是在IOS上登录,则不需要再进行其他信息的填写
设置Apple的后台信息
因为这个是之前已经设置好了,我这此并没有进行设置,就不误导人了,有问题可以去官网看一下,或者从文章最后的参考网址找答案
从Assets Store下载 Singn In With Apple
示例代码与示例场景,其中Start是初始化Apple登录,里面也包括了示例场景的初始化方法,如果是移植到实际项目中,把Start里面的代码去掉初始化场景的方法即可。
其次,Update中的代码是持续进行接受登录信息的代码。
如果要使用Apple登录其他服务,例如Firebase之类的,那么,要使用Apple的登录令牌生成一个随机码,这个随机码获取的时候先保存下来,然后将这个码转换为SHA256格式,使用这个SHA256格式的码去登录Apple,当登录成功后,获取Apple的登录令牌,这个令牌包含了你之前生成的随机码,如果登录其他服务的话,要使用这个令牌和你之前保存的随机码去创建这个第三方服务的登录令牌,创建的时候会去比较你保存的随机码和Apple给你返回的登录令牌里面包含的随机吗是否一致,如果不一致将导致登录失败!
Xcode设置
添加Apple登录框架:
1)在Signing&Capabilities中点击Capability,
添加Sign in with Apple
2)Build Phases中点击Link Binary with Libraries点击+号,
搜索AuthenticationServices.framework并添加
后续问题
证书权限
因为添加了IOS的登录权限,导致原来的证书不能用了,不需要做太多,只要到Apple开发这后台,把Profile点击编辑,不需要任何改动,直接保存,重新下载下来就可以了。参考网址在下面
ok,这样就可以登录到Apple了
Apple登录代码
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using AppleAuth;
using AppleAuth.Enums;
using AppleAuth.Extensions;
using AppleAuth.Interfaces;
using AppleAuth.Native;
using Firebase.Auth;
using Firebase.Extensions;
using UnityEngine;
public class AppleLoginManager : MonoDontDestroySingleTon<AppleLoginManager>
{
private const string AppleUserIdKey = "AppleUserId";
private const string AppleUserEmail = "AppleUserEmail";
private string rawNonce;
private IAppleIDCredential appleIdCredential;
private IAppleAuthManager _appleAuthManager;
private void Update()
{
if (this._appleAuthManager != null)
{
this._appleAuthManager.Update();
}
}
public void Init()
{
if (AppleAuthManager.IsCurrentPlatformSupported)
{
// Creates a default JSON deserializer, to transform JSON Native responses to C# instances
var deserializer = new PayloadDeserializer();
// Creates an Apple Authentication manager with the deserializer
this._appleAuthManager = new AppleAuthManager(deserializer);
}
}
public void Login(Action<bool> action = null)
{
if (_appleAuthManager == null && AppleAuthManager.IsCurrentPlatformSupported)
{
// Creates a default JSON deserializer, to transform JSON Native responses to C# instances
var deserializer = new PayloadDeserializer();
// Creates an Apple Authentication manager with the deserializer
this._appleAuthManager = new AppleAuthManager(deserializer);
}
rawNonce = GenerateRandomString(32);
string nonce = GenerateSHA256NonceFromRawNonce(rawNonce);
var loginArgs = new AppleAuthLoginArgs(LoginOptions.IncludeEmail | LoginOptions.IncludeFullName, nonce);
this._appleAuthManager.LoginWithAppleId(
loginArgs,
credential =>
{
// If a sign in with apple succeeds, we should have obtained the credential with the user id, name, and email, save it
//PlayerPrefs.SetString(AppleUserIdKey, credential.User);
appleIdCredential = credential as IAppleIDCredential;
if (appleIdCredential != null)
{
// Apple User ID
// You should save the user ID somewhere in the device
var userId = appleIdCredential.User;
PlayerPrefs.SetString(AppleUserIdKey, userId);
// Email (Received ONLY in the first login)
var email = appleIdCredential.Email;
PlayerPrefs.SetString(AppleUserEmail, email);
// Full name (Received ONLY in the first login)
var fullName = appleIdCredential.FullName;
// Identity token
var identityToken = System.Text.Encoding.UTF8.GetString(
appleIdCredential.IdentityToken,
0,
appleIdCredential.IdentityToken.Length);
// Authorization code
var authorizationCode = System.Text.Encoding.UTF8.GetString(
appleIdCredential.AuthorizationCode,
0,
appleIdCredential.AuthorizationCode.Length);
// And now you have all the information to create/login a user in your system
action?.Invoke(true);
}
},
error =>
{
var authorizationErrorCode = error.GetAuthorizationErrorCode();
action?.Invoke(false);
});
}
public void LoginToFirebase(Action<string> action)
{
if (appleIdCredential == null)
{
return;
}
var identityToken = Encoding.UTF8.GetString(appleIdCredential.IdentityToken);
var authorizationCode = Encoding.UTF8.GetString(appleIdCredential.AuthorizationCode);
var firebaseCredential = OAuthProvider.GetCredential(
"apple.com",
identityToken,
rawNonce,
authorizationCode);
FirebaseAuth.DefaultInstance.SignInWithCredentialAsync(firebaseCredential).ContinueWith(task =>
{
if (task.IsCanceled)
{
Debuger.LogError("SignInWithCredentialAsync was canceled.");
return;
}
else if (task.IsFaulted)
{
Debuger.LogError("SignInWithCredentialAsync encountered an error: " + task.Exception);
return;
}
Firebase.Auth.FirebaseUser newUser = task.Result;
Debuger.Log(string.Format("User signed in successfully: {0} ({1})",
newUser.DisplayName, newUser.UserId));
action?.Invoke(newUser.UserId);
});
}
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 System.Security.Cryptography.RNGCryptoServiceProvider();
var result = string.Empty;
var remainingLength = length;
var randomNumberHolder = new byte[1];
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 System.Security.Cryptography.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;
}
}
使用的时候只需要调用下面代码即可
AppleLoginManager.Instance.SignIn((isLogin) =>
{
if (isLogin)
{
AppleLoginManager.Instance.LoginToFirebase((UserId) =>
{
//登录到Firebase后的操作
});
}
else
{
Debuger.LogError($"Login is Fail");
}
});
参考文章:
此文章介绍了一下大概,其中包括Xode的一些操作
链接: https://blogs.unity3d.com/2019/09/19/support-for-apple-sign-in/
GitHub社区,介绍的也比较详细了
链接: https://github.com/lupidan/apple-signin-unity
包括生成随机码与将随机码转换为SHA256的代码在这里面也有:
链接: https://github.com/lupidan/apple-signin-unity/blob/master/docs/Firebase_NOTES.md
Firebase接入Apple的官方指导网址:
链接: https://firebase.google.com/docs/auth/unity/apple#on-ios
链接: https://firebase.google.com/docs/auth/ios/apple
证书权限问题解决参考网址:
链接: https://ask.dcloud.net.cn/article/id-36651__page-4