using System.Collections; using System.Collections.Generic; using UnityEngine; namespace Mirror.Authenticators { [AddComponentMenu("Network/ Authenticators/Basic Authenticator")] [HelpURL("https://mirror-networking.gitbook.io/docs/components/network-authenticators/basic-authenticator")] public class BasicAuthenticator : NetworkAuthenticator { [Header("Server Credentials")] public string serverUsername; public string serverPassword; [Header("Client Credentials")] public string username; public string password; readonly HashSet connectionsPendingDisconnect = new HashSet(); #region Messages public struct AuthRequestMessage : NetworkMessage { // use whatever credentials make sense for your game // for example, you might want to pass the accessToken if using oauth public string authUsername; public string authPassword; } public struct AuthResponseMessage : NetworkMessage { public byte code; public string message; } #endregion #region Server /// /// Called on server from StartServer to initialize the Authenticator /// Server message handlers should be registered in this method. /// public override void OnStartServer() { // register a handler for the authentication request we expect from client NetworkServer.RegisterHandler(OnAuthRequestMessage, false); } /// /// Called on server from StopServer to reset the Authenticator /// Server message handlers should be unregistered in this method. /// public override void OnStopServer() { // unregister the handler for the authentication request NetworkServer.UnregisterHandler(); } /// /// Called on server from OnServerConnectInternal when a client needs to authenticate /// /// Connection to client. public override void OnServerAuthenticate(NetworkConnectionToClient conn) { // do nothing...wait for AuthRequestMessage from client } /// /// Called on server when the client's AuthRequestMessage arrives /// /// Connection to client. /// The message payload public void OnAuthRequestMessage(NetworkConnectionToClient conn, AuthRequestMessage msg) { //Debug.Log($"Authentication Request: {msg.authUsername} {msg.authPassword}"); if (connectionsPendingDisconnect.Contains(conn)) return; // check the credentials by calling your web server, database table, playfab api, or any method appropriate. if (msg.authUsername == serverUsername && msg.authPassword == serverPassword) { // create and send msg to client so it knows to proceed AuthResponseMessage authResponseMessage = new AuthResponseMessage { code = 100, message = "Success" }; conn.Send(authResponseMessage); // Accept the successful authentication ServerAccept(conn); } else { connectionsPendingDisconnect.Add(conn); // create and send msg to client so it knows to disconnect AuthResponseMessage authResponseMessage = new AuthResponseMessage { code = 200, message = "Invalid Credentials" }; conn.Send(authResponseMessage); // must set NetworkConnection isAuthenticated = false conn.isAuthenticated = false; // disconnect the client after 1 second so that response message gets delivered StartCoroutine(DelayedDisconnect(conn, 1f)); } } IEnumerator DelayedDisconnect(NetworkConnectionToClient conn, float waitTime) { yield return new WaitForSeconds(waitTime); // Reject the unsuccessful authentication ServerReject(conn); yield return null; // remove conn from pending connections connectionsPendingDisconnect.Remove(conn); } #endregion #region Client /// /// Called on client from StartClient to initialize the Authenticator /// Client message handlers should be registered in this method. /// public override void OnStartClient() { // register a handler for the authentication response we expect from server NetworkClient.RegisterHandler(OnAuthResponseMessage, false); } /// /// Called on client from StopClient to reset the Authenticator /// Client message handlers should be unregistered in this method. /// public override void OnStopClient() { // unregister the handler for the authentication response NetworkClient.UnregisterHandler(); } /// /// Called on client from OnClientConnectInternal when a client needs to authenticate /// public override void OnClientAuthenticate() { AuthRequestMessage authRequestMessage = new AuthRequestMessage { authUsername = username, authPassword = password }; NetworkClient.Send(authRequestMessage); } /// /// Called on client when the server's AuthResponseMessage arrives /// /// The message payload public void OnAuthResponseMessage(AuthResponseMessage msg) { if (msg.code == 100) { //Debug.Log($"Authentication Response: {msg.message}"); // Authentication has been accepted ClientAccept(); } else { Debug.LogError($"Authentication Response: {msg.message}"); // Authentication has been rejected ClientReject(); } } #endregion } }