メインコンテンツまでスキップ

認証

MCE Onlineレイヤーは、Nakamaを通じて複数の認証方法をサポートしています。すべての認証フローは、AuthService(Auth/AuthService.cs内)とSessionManagerによって管理され、どちらも起動時にNakamaManagerによって自動的に初期化されます。

MCE Online のサインイン画面

この画面はエンジンに同梱されており、以下の3つのフロー(メール/パスワード、アカウント作成、SSO プロバイダー)をカバーしています。モックアップではなく、実際に動作しているゲームの画面です。

接続状態​

ConnectionState列挙型は、オンライン接続のライフサイクル全体を追跡します:

状態説明
Disconnected未接続、接続試行もなし
Connecting現在接続を確立中
Connected接続および認証が成功
Reconnecting接続喪失、自動再接続を試行中
Offlineオフラインモードで実行中(サーバー利用不可または無効)
Failedすべての再試行後に接続失敗

状態変更はNakamaManager.Instance.OnStateChangedで購読できます。

NakamaManager.Instance.OnStateChanged += (state) =>
{
Debug.Log($"Connection state: {state}");
};

NakamaManagerには便利なプロパティがあります:

  • IsConnected — 状態がConnectedの場合のみtrueを返します。
  • IsOffline — 状態がOfflineまたはDisconnectedの場合にtrueを返します。

認証方法​

MCEは以下のAuthMethod値をサポートしています:Email、DeviceId、Discord、Google、Apple、Facebook、Custom。

デバイス認証(自動ログイン)​

最もシンプルな方法。SystemInfo.deviceUniqueIdentifierを使用して匿名アカウントを自動的に作成します。モバイルや初回プレイに最適です。

bool success = await NakamaManager.Instance.ConnectWithDeviceAsync();

内部的には、これは NakamaManager の単一の接続パイプラインであり、Client.AuthenticateDeviceAsync(deviceId, create: true) を呼び出します。初回使用時に新しいNakamaアカウントを作成し、以降の呼び出しでログインします。(AuthService は同じパイプラインの上に載る薄いファサードなので、認証する方法はちょうど1つです。)デバイスIDはプライバシーのためログで切り詰められます。

メール/パスワード認証​

登録(create: true)とログイン(create: false)の両方をサポートしています。

// 新規アカウント登録
bool registered = await NakamaManager.Instance.ConnectWithEmailAsync(
"player@example.com", "securepassword", createAccount: true);

// 既存アカウントにログイン
bool loggedIn = await NakamaManager.Instance.ConnectWithEmailAsync(
"player@example.com", "securepassword", createAccount: false);

セッションを返す AuthService ファサードを経由することもできます:

OnlineSession session = await NakamaManager.Instance.Auth.AuthenticateEmailAsync(
email, password, create: true);

返されるOnlineSessionはNakamaのISessionをラップし、UserId、DisplayName、Token、RefreshToken、ExpiresAtを公開します。

SSO認証(Discord、Google、Apple)​

SSOプロバイダーはOnlineConfigでプロバイダーごとに有効化されます:

  • EnableDiscordSSO(デフォルト:true)
  • EnableGoogleSSO(デフォルト:true)
  • EnableAppleSSO(デフォルト:true)

OAuthクライアントIDもOnlineConfigで設定されます(DiscordClientId、GoogleClientId)。

// Google
bool success = await NakamaManager.Instance.ConnectWithSSOAsync(
AuthMethod.Google, googleIdToken);

// Apple
bool success = await NakamaManager.Instance.ConnectWithSSOAsync(
AuthMethod.Apple, appleIdentityToken);

// Discord(DiscordユーザーIDを使用したカスタム認証フロー)
bool success = await NakamaManager.Instance.ConnectWithSSOAsync(
AuthMethod.Discord, discordUserId);

GoogleとAppleはNakamaの組み込みAuthenticateGoogleAsync / AuthenticateAppleAsyncを使用します。DiscordとFacebookはNakamaにネイティブのDiscord認証プロバイダーがないため、AuthenticateCustomAsyncを経由します。

アカウントリンク​

プレイヤーは複数の認証方法を1つのアカウントにリンクできます。これにより、デバイス認証で始めて、後でメールやSSOを追加してクロスデバイスアクセスが可能になります。

bool linked = await NakamaManager.Instance.Auth.LinkAccountAsync(
AuthMethod.Google, googleToken);

bool linked = await NakamaManager.Instance.Auth.LinkAccountAsync(
AuthMethod.Discord, discordToken);

LinkAccountAsyncはメソッドに応じてClient.LinkGoogleAsync、Client.LinkAppleAsync、またはClient.LinkCustomAsyncを使用します。

セッションの永続化​

SessionManagerはPlayerPrefsを使用して認証トークンの保存と復元を処理します:

  • トークンキー:mce_nakama_token
  • リフレッシュトークンキー:mce_nakama_refresh

認証成功時に、SaveNakamaSession(session)が両方のトークンを永続化します。アプリ再起動時に、LoadNakamaSession(client)がNakama.Session.Restore(token, refresh)を介してセッションを復元します。復元されたセッションが期限切れの場合は、自動的にクリアされます。

// 有効なセッションが存在するか確認
bool hasSession = NakamaManager.Instance.SessionMgr.HasValidSession();

// 手動でセッションをクリア(ログアウト)
NakamaManager.Instance.SessionMgr.ClearSession();

認証後フロー​

認証成功後、NakamaManager.FinalizeConnection()が以下のシーケンスを実行します:

  1. Session、UserId、DisplayName、SessionTokenを保存します。
  2. SessionManagerを介してセッションを保存します。
  3. Client.NewSocket(useMainThread: true)でWebSocketを作成します。
  4. ソケットイベントをフックします:Closed、ReceivedError、ReceivedMatchState、ReceivedChannelMessage、ReceivedNotification、ReceivedMatchmakerMatched、ReceivedStatusPresence。
  5. Socket.ConnectAsync(session)でソケットを接続します。
  6. オンラインサービスを非同期で初期化します:
    • WorldSync.InitializeAsync() — ワールドマッチに参加します。
    • Chat.JoinGlobalChannelAsync() — グローバルチャットルームに参加します。
    • Friends.RefreshFriendsListAsync() — フレンドを読み込み、ステータスをフォローします。
    • Housing.InitializeAsync() — EnableHousingがオンの場合。
    • Mods.LoadInstalledModsAsync() — EnableModSupportがオンの場合。
  7. OnConnectedを発火し、OnlineCommandBridgeを登録します。

自動再接続​

ソケットが予期せず閉じられ、OnlineConfig.AutoReconnectがtrueの場合、NakamaManagerは指数バックオフを使用して自動的に再接続を試みます:

  • 遅延式:min(2 * 2^(試行回数-1), 30)秒。
  • 最大試行回数:OnlineConfig.MaxReconnectAttempts(デフォルト:5)。
  • 再接続は保存されたセッションから復元します。セッションが期限切れの場合は、オフラインモードにフォールバックします。

試行中は状態がReconnectingに遷移します。

オフラインフォールバック​

OnlineConfig.AllowOfflineFallbackがtrue(デフォルト)の場合、接続失敗はConnectionState.Offlineにグレースフルにフォールバックします。ゲーム全体はローカルで動作し続けます — オンラインレイヤーは完全にオプショナルです。

表示名​

認証後、プレイヤーの表示名を更新できます:

bool updated = await NakamaManager.Instance.Auth.UpdateDisplayNameAsync("NewName");

エラーハンドリング​

認証エラーはNakamaManager.OnConnectionErrorイベントを通じて通知されます:

NakamaManager.Instance.OnConnectionError += (errorMessage) =>
{
Debug.LogError($"Connection error: {errorMessage}");
// プレイヤーにエラーダイアログを表示
};

すべての認証メソッドは内部で例外をキャッチし、[MCE Online]または[Auth]プレフィックスでログに記録します。

設定リファレンス​

OnlineConfig(Resources/OnlineConfigのScriptableObject)の主要設定:

フィールドデフォルト説明
ServerHost127.0.0.1Nakamaサーバーのホスト名
ServerPort7350Nakamaサーバーのポート
ServerKeydefaultkeyNakamaサーバーキー
UseSSLfalseHTTPS/WSSを使用
ConnectionTimeout10タイムアウト(秒)
AutoReconnecttrue切断時に自動再接続
MaxReconnectAttempts5最大再試行回数
AllowOfflineFallbacktrue失敗時にオフラインモードにフォールバック
EnableDiscordSSOtrueDiscord認証を有効化
EnableGoogleSSOtrueGoogle認証を有効化
EnableAppleSSOtrueApple認証を有効化

セキュリティのベストプラクティス​

  • 配布用ビルドでServerKeyを公開しないでください。Nakamaの環境固有キーを使用してください。
  • 本番環境ではSSOまたはメール認証を推奨します。デバイス認証は開発やモバイルのクイックスタートに便利ですが、デバイスが初期化されると復元できません。
  • 本番環境ではOnlineConfigでEnableServerAuthorityを有効化してください。これにより、すべての状態変更操作(アイテム、お金、テレポート)がOnlineCommandBridgeを介したサーバー検証を通るようになります。
  • セッショントークンはPlayerPrefsに保存されます。PlayerPrefsが安全でないプラットフォーム(PCなど)では、保存時にトークンを暗号化することを検討してください。