Photon Cloudでサーバーにカスタムロジックを載せずに使えるユーザー認証機能を触ってみた

Unityエンジニアの岡村です。

Unityでのアプリ開発において、リアルタイム通信の実装にはExitGames社のPhoton Realtime及び、Photon RealtimeをUnity向けのAPIでラップしたPhoton Unity Networking(PUN)が広く使われています。Photon Realtime及びPUNはサーバーの存在を前提とした通信エンジンで、Photon ServerもしくはPhoton Cloudを選択する事が出来ます。小規模なスマホアプリやゲームでは、アプリ開発者側がリアルタイムサーバーを用意する必要のないPhoton Cloudが人気です。

一方で、Photon CloudはEnterpriseプランでない限りサーバー上にアプリ固有の処理を載せることが出来ない為、カスタマイズ性に関してはPhoton Serverに劣ります。カスタマイズが出来ないことは、セキュリティ対策の観点において大きな懸念事項となります。そこで、今回はPhoton CloudのEnterpriseプランを契約しない範囲ではどの程度セキュリティ対策が出来るのかを調べ、触ってみた記録を紹介します。

Photon Cloudの認証機能

Photon Cloudはデフォルトで認証機能を持っており、以下を認証プロバイダーとして利用することが出来ます:

  • Steam
  • Facebook
  • VIVEPORT
  • Oculus
  • カスタム認証

どの認証方法でも、認証に成功した時のみPhotonサーバーに接続することが出来るという挙動になります。

また、認証に成功した場合、プロバイダはユーザーIDやニックネームなどの追加情報をクライアントに返すことが出来ます。

簡単なカスタム認証サーバーを用意してテストする

こちらの公式ドキュメントによると、Jsonを返すWebサーバーがあればカスタム認証が実装できそうです。 doc.photonengine.com

という事で、node.jsngrokを利用してローカルPC上に簡単な認証サーバーを立てて挙動を試してみました。

フォルダの作成、依存ライブラリのインストール

任意のフォルダを作成してnpm initで初期化した後、そのフォルダ内でnpm install expressを実行し、expressをインストールします。

サーバーコードの記述

次のコードをserver.jsとして、作成したフォルダ内に保存します。

var express = require('express');
var app = express();

app.get('/auth', function (req, res) {
    console.log(JSON.stringify(req.url));
    console.log(JSON.stringify(req.headers));

    // 必要なパラメーターが渡されているか確認
    if (!('userId' in req.query && 'password' in req.query)) {
        res.json({ ResultCode: 3, Message: "[AuthServer]Missing Parameters" });
        return;
    }

    let userId = req.query.userId;
    let password = req.query.password;

    // 渡されたパラメーターが正しいか確認
    if (!(userId === 'user01' && password === 'password')) {
        res.json({ ResultCode: 2, Message: "[AuthServer]Invalid UserID or Password" });
        return;
    }

    // 認証成功
    res.json({ ResultCode: 1, UserID: userId, Message: "[AuthServer]Authenticated" });
});

app.listen(3000);
console.log("server listening ...");

サーバーの実行

フォルダ内でnode serverを実行する事で、先ほど作成したserver.jsが読み込まれてサーバーが起動します。

サーバーの公開

ngrok http 3000を実行する事でローカルの3000番ポートがhttpサーバーとしてインターネットに公開されます。

3000番という値はserver.js内で指定している値ですので、そのポートが使用中の場合はserver.js内の記述と共に変更してください。 また、ngrokで生成されるURLはフリープランの場合、起動するたびに毎回ランダムな値に変化する為注意して下さい。

Photon Cloudの設定

Photon Cloudのコンソール上で、カスタム認証サーバーを設定します。

認証URLは先ほど起動したngrokで生成されたものを指定します。また、クライアントがいない場合、全てのクライアントを拒否する設定のチェックを入れておきます。(訳がおかしいですが、これは認証サーバーが応答していない場合、全てのクライアントの接続を拒否する設定の様です。)

今回はテストなので、認証処理が走っていることを分かりやすくするために、匿名クライアントの接続を許可する設定のチェックを外します。

クライアント側認証処理の記述

クライアント側の接続を行う前の箇所に、以下の処理を追記します。

AuthenticationValues authValues = new AuthenticationValues();
authValues.AuthType = CustomAuthenticationType.Custom;
// サーバー側ロジックで要求しているものと同じuserIdとpasswordをパラメータとして設定する
authValues.AddAuthParameter("userId", "user01");
authValues.AddAuthParameter("password", "password");
 
loadBalancingClient.AuthValues = authValues; // Photon Realtimeの場合
PhotonNetwork.AuthValues = authValues; // PUNの場合

// この先に接続処理を書く

挙動確認

まず、認証パラメータを渡さないクライアントで接続してみます。

次に、パラメータは渡すが値が誤っているクライアントで接続してみます。

最後に、パラメータとその値が正しいクライアントで接続してみます。

エラーが出ておらず、接続に成功しました。

ちなみに、クライアント及びクラウドコンソールで指定したパラメータは以下のようにURLクエリパラメータとして渡されます。

以上

上記のコードや構成はテスト用に書いたものなのでかなり雑です。少なくとも本番利用する際にはIDパスワードを直接渡すのではなく、他のルートで発行して貰った一時的なコードを渡す等の対応をした方が良さそうです。しかし、今回node.jsやngrokを利用する事で、とても簡単に認証の流れをテストできて面白さを感じたため載せてみました。

という事で、本格的にオンラインを活用するゲームであればゲームサーバーは必須ですが、Photon Cloudでも最低限の認証機構が搭載出来る!というご紹介でした。

宣伝

Synamonは、Unity / C#エンジニア、テックリードを中心に新しい仲間を募集中です。 「XRが当たり前の世界をつくる」というミッションに共感したメンバーが、切磋琢磨しながら日々挑戦しています!カジュアル面談も実施中なので、ご興味ある方、お気軽にご連絡ください。

カジュアル面談はこちらから meety.net

エントリーはこちらから herp.careers

また、本テックブログやnote記事のお知らせは、Synamon公式Twitterでも発信もしています。 弊社の取り組みに興味を持っていただけたら、ぜひフォローをお願い致します!
twitter.com