Twitter認証(OAuth) - UnityでSDKなしでFirebaseを使う
概要
UnityのプロジェクトにTwitterのアカウントでの認証機能を導入する方法を解説します。
TwitterのOAuthを利用して認証を行うため、Unityから直接APIは叩かずWebViewを使って認可を取得するところがポイントです。
この投稿はUnityでSDKなしでFirebaseを使うの一部です。
途中で出てくるソースコードの全体は以下にあります。
Unity側:
Firebase側:
Twitterのデベロッパー登録とアプリケーションの作成
詳細な手順は省略しますが、Twitter Developer Platformにサインインします。
サインインができたら次にプロジェクトとアプリケーションの設定を行います。
以下のdashboardを開いて、Create Project
からプロジェクトとアプリケーションを作成します。
以下の用にサイドメニューにプロジェクトとアプリケーションが表示されればアプリケーションの作成は完了です。
Firebase AuthenticationとTwitter Appの設定
Twitter Appの Key and Tokens
タブの API Key and Secret
の Regenerate
ボタンでトークンを作成します。
作成した API Key
と API Secret Key
はこの後のFirebaseg側の設定で使用するので開いたままにしておきます。
次にFirebase Authenticationの Sign-in method
タブでTwitter認証を有効にします。
APIキーとAPIシークレットには先ほどTwitterで生成した API Key
と API Secret Key
を設定します。
コールバックURL
はこの後Twitterの設定に使用するので控えた後に保存します。
Developer Portalに戻って、Appの Settings
タブの 3-legged OAuth
を有効にします。
有効にすると各設定項目が入力できるようになるので、必要項目を入力します。
Callback URLs
には先ほどFierbaseで表示された コールバックURL
を設定します。
入力が終わったら保存します。
OAuth用のWebページ作成
ユーザーから認可を得るためのページを作成します。
ローカルのFirebase開発環境のpublicフォルダの配下にhtmlファイルを作成します。
以下のサンプルコードのいくつかのポイントを説明しますが、その他の設定等については参考にリンクを貼ったリポジトリを参照してください。
-
firebasejsのバージョン
https://www.gstatic.com/firebasejs/~
に指定するバージョンはFirebaseの プロジェクトの設定のマイアプリに記載されているスクリプトのバージョンと合わせるようにしてください。
-
firebaseConfigの設定
各設定内容についてはfirebasejsと同様マイアプリに記載されています。 -
signInSuccessWithAuthResult
認証結果のトークンをUnity側に渡すためにUnity.callを呼んでいます。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Sample FirebaseUI App</title>
<script src="https://www.gstatic.com/firebasejs/8.6.7/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.6.7/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/ui/4.8.0/firebase-ui-auth.js"></script>
<link type="text/css" rel="stylesheet" href="https://www.gstatic.com/firebasejs/ui/4.8.0/firebase-ui-auth.css"/>
<script>
// https://github.com/gree/unity-webview/issues/681
if (window && window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.unityControl) {
window.Unity = {
call: function (msg) {
window.webkit.messageHandlers.unityControl.postMessage(msg);
}
}
} else {
window.Unity = {
call: function (msg) {
window.location = 'unity:' + msg;
}
}
}
</script>
<script type="text/javascript">
var firebaseConfig = {
apiKey: "****",
authDomain: "****",
projectId: "****",
storageBucket: "****",
messagingSenderId: "****",
appId: "****",
measurementId: "****"
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
// FirebaseUI config.
var uiConfig = {
callbacks: {
signInSuccessWithAuthResult: function (authResult, redirectUrl) {
console.log(authResult);
Unity.call(JSON.stringify(authResult));
return false;
},
},
signInSuccessUrl: 'https://localhost',
signInOptions: [
firebase.auth.GoogleAuthProvider.PROVIDER_ID,
firebase.auth.FacebookAuthProvider.PROVIDER_ID,
firebase.auth.TwitterAuthProvider.PROVIDER_ID,
firebase.auth.GithubAuthProvider.PROVIDER_ID,
firebase.auth.EmailAuthProvider.PROVIDER_ID,
firebase.auth.PhoneAuthProvider.PROVIDER_ID,
firebaseui.auth.AnonymousAuthProvider.PROVIDER_ID
],
tosUrl: '<your-tos-url>',
privacyPolicyUrl: function () {
window.location.assign('<your-privacy-policy-url>');
}
};
// Initialize the FirebaseUI Widget using Firebase.
var ui = new firebaseui.auth.AuthUI(firebase.auth());
// The start method will wait until the DOM is loaded.
ui.start('#firebaseui-auth-container', uiConfig);
</script>
</head>
<body>
<h1>Welcome to My Awesome App</h1>
<div id="firebaseui-auth-container"></div>
</body>
</html>
htmlが作成できたら firebase deploy --only hosting
コマンドの実行または、GitHub Actionの設定ができている場合はmainブランチを更新することでデプロイされます。
デプロイ後にFirebaseのHostingのダッシュボードにドメインが表示されるので、
ドメイン+ローカルで作ったpublic配下のパスのurlでアクセスできます。
例: https://fb-vanilla-sample.firebaseapp.com/auth/auth.html
参考:
認可取得用のUnityのWebViewの実装
今回は gree/unity-webview を使用してWebViewを扱うので、Unityプロジェクトのmanifest.jsonに以下の依存を追加します。
"net.gree.unity-webview": "https://github.com/gree/unity-webview.git?path=/dist/package"
WebViewの表示とOAuthの結果受け取り
以下のようなUnityからOAuthのフローを行うためのWebViewを表示する部分を実装します。
private string url = "OAuth用のWebページのURL";
WebViewObject webViewObject;
void Start()
{
webViewObject =
(new GameObject("WebViewObject")).AddComponent<WebViewObject>();
webViewObject.Init((msg) =>
{
// WebViewからのOAuthの結果のメッセージをmsgで受け取れるのでJsonからオブジェクトに変換
// サインインを実装しているクラスから使えるように設定する
TwitterScript.oAuthResult = TwitterApi.OAuthResultObject.FromJson(msg);
GameObject.Find("Canvas/SignInButton").GetComponent<Button>().interactable = true;
webViewObject.SetVisibility(false);
});
webViewObject.LoadURL(url);
webViewObject.SetMargins(50, 100, 50, 50);
webViewObject.SetVisibility(true);
}
UnityからのOAuthを使ったサインイン
AccessTokenとAccessTokenSecretを使って、Firebase Authenticationにサインインする部分の実装です。
private string _apiKey = "APIキー";
// WebViewからの送られてきたOAuthの結果が入っているオブジェクト
public static TwitterApi.OAuthResultObject oAuthResult;
public void SignIn()
{
WebClient wc = new WebClient();
wc.Headers[HttpRequestHeader.ContentType] = "application/json";
var url = $"https://identitytoolkit.googleapis.com/v1/accounts:signInWithIdp?key={_apiKey}";
var requestBody = FirebaseApi.SignInWithIdpRequest.SignInWithIdpTwitterRequest(
oAuthResult.credential.oauthAccessToken,
oAuthResult.credential.oauthTokenSecret
).ToJson();
var response = wc.UploadString(new Uri(url), requestBody);
var authResult = FirebaseApi.SignInWithIdpResponse.FromJson(response);
Debug.Log($"idToken: {authResult.idToken}");
Debug.Log($"refreshToken: {authResult.refreshToken}");
}
レスポンスに返ってくるidTokenとrefreshTokenをローカルストレージなどに保存しておくことで、パスワードなどを扱わずに安全に認証することができます。
Discussion
こんにちは。コメント失礼いたします。
3月よりUnityを触り始め、TwitterApiを利用してデータを取得するアプリを作っています。
OAuth認証の段階で何日も時間を費やしており、、そこでsatousoさんの記事を見つけて、どの記事よりも詳しく書かれていたのでもうすぐ山を越えられると思ってわくわくしています!
しかし、UIをどう実装すればよいかで戸惑っております。。。
TwitterScript.cs のSighInメソッドをUnityで作成したButtonにアタッチさせればいいとは思っているのですが、いざ実行してみると「Object reference not set to an instance of an object」というエラーが出てきてしまいます。
「あ、なるほど、、Githubで作成したHTMLをimageとかに反映させればいいのね、」と解釈したのですが、どのように表示させればいいのか分からず、イメージも付けられず、、、
どのようにしたら「WebViewの表示とOAuthの結果受け取り」のような画面を表示させることができるのでしょうか?
ご教示いただけますと幸いです。
よろしくお願いいたします。
誤認識の通りTwitterScript.csはButtonにアタッチさせれば良いです。WebViewを表示させている
WebViewについてはシーン内に適当な空のオブジェクトを作ってそのオブジェクトにAuthWebViewScript.csをアタッチさせれば動くかと思います。
(AuthWebViewScript.csのStart()内でWebViewを表示させる用のオブジェクトを作ってそこにWebViewを表示させるのでImageとかは自分で作らなくて良いです。)
Firebase側の設定ができていたら試せるサンプル用のリポジトリも用意してあるので、もし何かわからないことがあればこちらも見てみてください。
細かな説明がなくて分かりにくいところもあるかと思うので、うまく行かない所があればお気軽にお声がけください😉