Saltar al contenido principal

Autenticación

La capa Online de MCE soporta múltiples métodos de autenticación a través de Nakama. Todos los flujos de autenticación son gestionados por AuthService (en Auth/AuthService.cs) y SessionManager, ambos inicializados automáticamente por NakamaManager al inicio.

La pantalla de inicio de sesión de MCE Online

La pantalla se incluye con el motor y cubre los tres flujos de abajo: correo/contraseña, creación de cuenta y los proveedores SSO. Nada de esto es una maqueta: es el juego en ejecución.

Estados de Conexión​

El enum ConnectionState sigue el ciclo de vida completo de la conexión online:

EstadoDescripción
DisconnectedNo conectado y sin intentar conectar
ConnectingIntentando establecer conexión actualmente
ConnectedConectado y autenticado exitosamente
ReconnectingConexión perdida, intentando reconexión automática
OfflineEjecutándose en modo offline (servidor no disponible o deshabilitado)
FailedConexión fallida después de todos los intentos

Puedes suscribirte a los cambios de estado via NakamaManager.Instance.OnStateChanged.

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

Hay propiedades de conveniencia disponibles en NakamaManager:

  • IsConnected — devuelve true solo cuando el estado es Connected.
  • IsOffline — devuelve true cuando el estado es Offline o Disconnected.

Métodos de Autenticación​

MCE soporta los siguientes valores de AuthMethod: Email, DeviceId, Discord, Google, Apple, Facebook y Custom.

Autenticación por Dispositivo (Auto-Login)​

El método más simple. Usa SystemInfo.deviceUniqueIdentifier para crear una cuenta anónima automáticamente. Ideal para móviles y primera partida.

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

Internamente esto es el único pipeline de conexión de NakamaManager, que llama a Client.AuthenticateDeviceAsync(deviceId, create: true): crea una nueva cuenta de Nakama en el primer uso e inicia sesión en llamadas posteriores. (AuthService es una fachada delgada sobre ese mismo pipeline, así que hay exactamente una forma de autenticarse.) El ID de dispositivo se trunca en los logs por privacidad.

Autenticación por Email / Contraseña​

Soporta tanto registro (create: true) como inicio de sesión (create: false).

// Registrar una cuenta nueva
bool registered = await NakamaManager.Instance.ConnectWithEmailAsync(
"player@example.com", "securepassword", createAccount: true);

// Iniciar sesión en cuenta existente
bool loggedIn = await NakamaManager.Instance.ConnectWithEmailAsync(
"player@example.com", "securepassword", createAccount: false);

También puedes pasar por la fachada AuthService, que devuelve la sesión:

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

El OnlineSession devuelto encapsula ISession de Nakama y expone: UserId, DisplayName, Token, RefreshToken y ExpiresAt.

Autenticación SSO (Discord, Google, Apple)​

Los proveedores SSO se habilitan por proveedor en OnlineConfig:

  • EnableDiscordSSO (default: true)
  • EnableGoogleSSO (default: true)
  • EnableAppleSSO (default: true)

Los IDs de cliente OAuth también se configuran en OnlineConfig (DiscordClientId, GoogleClientId).

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

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

// Discord (usa flujo de autenticación personalizado con ID de usuario de Discord)
bool success = await NakamaManager.Instance.ConnectWithSSOAsync(
AuthMethod.Discord, discordUserId);

Google y Apple usan AuthenticateGoogleAsync / AuthenticateAppleAsync integrados de Nakama. Discord y Facebook usan AuthenticateCustomAsync ya que Nakama no tiene un proveedor de autenticación nativo para Discord.

Vinculación de Cuentas​

Los jugadores pueden vincular múltiples métodos de autenticación a una sola cuenta. Esto les permite comenzar con autenticación de dispositivo y luego agregar email o SSO para acceso multi-dispositivo.

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

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

LinkAccountAsync usa Client.LinkGoogleAsync, Client.LinkAppleAsync o Client.LinkCustomAsync según el método.

Persistencia de Sesión​

SessionManager maneja el guardado y restauración de tokens de autenticación usando PlayerPrefs:

  • Clave de token: mce_nakama_token
  • Clave de token de actualización: mce_nakama_refresh

En la autenticación exitosa, SaveNakamaSession(session) persiste ambos tokens. Al reiniciar la aplicación, LoadNakamaSession(client) restaura la sesión via Nakama.Session.Restore(token, refresh). Si la sesión restaurada está expirada, se limpia automáticamente.

// Verificar si existe una sesión válida
bool hasSession = NakamaManager.Instance.SessionMgr.HasValidSession();

// Limpiar sesión manualmente (cerrar sesión)
NakamaManager.Instance.SessionMgr.ClearSession();

Flujo Post-Autenticación​

Después de cualquier autenticación exitosa, NakamaManager.FinalizeConnection() ejecuta la siguiente secuencia:

  1. Almacena Session, UserId, DisplayName y SessionToken.
  2. Guarda la sesión via SessionManager.
  3. Crea un WebSocket via Client.NewSocket(useMainThread: true).
  4. Conecta eventos del socket: Closed, ReceivedError, ReceivedMatchState, ReceivedChannelMessage, ReceivedNotification, ReceivedMatchmakerMatched, ReceivedStatusPresence.
  5. Conecta el socket con Socket.ConnectAsync(session).
  6. Inicializa servicios online de forma asíncrona:
    • WorldSync.InitializeAsync() — se une al match mundial.
    • Chat.JoinGlobalChannelAsync() — se une al chat global.
    • Friends.RefreshFriendsListAsync() — carga amigos y sigue su estado.
    • Housing.InitializeAsync() — si EnableHousing está activado.
    • Mods.LoadInstalledModsAsync() — si EnableModSupport está activado.
  7. Dispara OnConnected y registra el OnlineCommandBridge.

Reconexión Automática​

Cuando el socket se cierra inesperadamente y OnlineConfig.AutoReconnect es true, NakamaManager intenta reconectarse automáticamente usando backoff exponencial:

  • Fórmula de retardo: min(2 * 2^(intento-1), 30) segundos.
  • Máximo de intentos: OnlineConfig.MaxReconnectAttempts (default: 5).
  • La reconexión restaura desde la sesión guardada. Si la sesión expiró, cae a modo offline.

El estado transiciona a Reconnecting durante los intentos.

Fallback Offline​

Cuando OnlineConfig.AllowOfflineFallback es true (por defecto), cualquier fallo de conexión cae gracefulmente a ConnectionState.Offline. Todo el juego continúa funcionando localmente — la capa online es completamente opcional.

Nombre de Visualización​

Después de la autenticación, puedes actualizar el nombre de visualización del jugador:

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

Manejo de Errores​

Los errores de autenticación se muestran a través del evento NakamaManager.OnConnectionError:

NakamaManager.Instance.OnConnectionError += (errorMessage) =>
{
Debug.LogError($"Connection error: {errorMessage}");
// Mostrar diálogo de error al jugador
};

Todos los métodos de autenticación capturan excepciones internamente y las registran con el prefijo [MCE Online] o [Auth].

Referencia de Configuración​

Configuraciones clave en OnlineConfig (ScriptableObject en Resources/OnlineConfig):

CampoDefaultDescripción
ServerHost127.0.0.1Hostname del servidor Nakama
ServerPort7350Puerto del servidor Nakama
ServerKeydefaultkeyClave del servidor Nakama
UseSSLfalseUsar HTTPS/WSS
ConnectionTimeout10Timeout en segundos
AutoReconnecttrueReconexión automática al desconectar
MaxReconnectAttempts5Cantidad máxima de reintentos
AllowOfflineFallbacktrueFallback a modo offline en caso de fallo
EnableDiscordSSOtrueHabilitar autenticación de Discord
EnableGoogleSSOtrueHabilitar autenticación de Google
EnableAppleSSOtrueHabilitar autenticación de Apple

Mejores Prácticas de Seguridad​

  • Nunca expongas ServerKey en builds destinados a distribución. Usa las claves específicas del entorno de Nakama.
  • Prefiere SSO o autenticación por email para producción. La autenticación por dispositivo es conveniente para desarrollo y inicio rápido en móviles, pero no se puede recuperar si el dispositivo se borra.
  • Activa EnableServerAuthority en OnlineConfig para producción. Esto enruta todas las operaciones de cambio de estado (objetos, dinero, teletransporte) a través de validación del servidor via el OnlineCommandBridge.
  • Los tokens de sesión se almacenan en PlayerPrefs. En plataformas donde PlayerPrefs no es seguro (ej., PC), considera encriptar el token en reposo.