using System; using UnityEngine; namespace Mirror.Authenticators { /// /// An authenicator that identifies the user by their device. /// A GUID is used as a fallback when the platform doesn't support SystemInfo.deviceUniqueIdentifier. /// Note: deviceUniqueIdentifier can be spoofed, so security is not guaranteed. /// See https://docs.unity3d.com/ScriptReference/SystemInfo-deviceUniqueIdentifier.html for details. /// [AddComponentMenu("Network/ Authenticators/Device Authenticator")] [HelpURL("https://mirror-networking.gitbook.io/docs/components/network-authenticators/device-authenticator")] public class DeviceAuthenticator : NetworkAuthenticator { #region Messages public struct AuthRequestMessage : NetworkMessage { public string clientDeviceID; } public struct AuthResponseMessage : NetworkMessage { } #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 registered in this method. /// public override void OnStopServer() { // unregister the handler for the authentication request NetworkServer.UnregisterHandler(); } /// /// Called on server from OnServerAuthenticateInternal when a client needs to authenticate /// /// Connection to client. public override void OnServerAuthenticate(NetworkConnectionToClient conn) { // do nothing, wait for client to send his id } void OnAuthRequestMessage(NetworkConnectionToClient conn, AuthRequestMessage msg) { Debug.Log($"connection {conn.connectionId} authenticated with id {msg.clientDeviceID}"); // Store the device id for later reference, e.g. when spawning the player conn.authenticationData = msg.clientDeviceID; // Send a response to client telling it to proceed as authenticated conn.Send(new AuthResponseMessage()); // Accept the successful authentication ServerAccept(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 OnClientAuthenticateInternal when a client needs to authenticate /// public override void OnClientAuthenticate() { string deviceUniqueIdentifier = SystemInfo.deviceUniqueIdentifier; // Not all platforms support this, so we use a GUID instead if (deviceUniqueIdentifier == SystemInfo.unsupportedIdentifier) { // Get the value from PlayerPrefs if it exists, new GUID if it doesn't deviceUniqueIdentifier = PlayerPrefs.GetString("deviceUniqueIdentifier", Guid.NewGuid().ToString()); // Store the deviceUniqueIdentifier to PlayerPrefs (in case we just made a new GUID) PlayerPrefs.SetString("deviceUniqueIdentifier", deviceUniqueIdentifier); } // send the deviceUniqueIdentifier to the server NetworkClient.connection.Send(new AuthRequestMessage { clientDeviceID = deviceUniqueIdentifier } ); } /// /// Called on client when the server's AuthResponseMessage arrives /// /// The message payload public void OnAuthResponseMessage(AuthResponseMessage msg) { Debug.Log("Authentication Success"); ClientAccept(); } #endregion } }