身份验证
# 我们将首先讨论多人游戏的一个更重要的功能:让玩家能够证明自己的用户身份,并相互交流。
Nakama 可帮助我们实现这一点,其方法是让您可以轻松创建存储和处理数据的集中化服务器 ,并让玩家(客户端 )可以连接到服务器。
建立连接
# 在此我们连接 Unity 客户端和 Nakama 服务器。
第一步是在 Unity 中游戏开始时注册一个新的 Client 对象。该对象将是在客户端和服务器之间进行任何交互的界面。
下面是对客户端进行初始化的主菜单脚本的片段:
Scene01MainMenuController.cs
1
2
var client = new Client ( "http" , "localhost" , 7350 , "defaultkey" , UnityWebRequestAdapter . Instance );
client . Timeout = 5 ;
在此我们传送以下连接值,创建连到您在本地启动的服务器(位于 http://localhost:7350
)的连接:
Scheme
:连接方案,此处为 http
。Host
:服务器主机,对于本例为 localhost
。Port
:服务器端口,默认设置为 7350
。ServerKey
:默认使用 defaultkey
。可通过服务器配置 更改。设备身份验证
# 建立服务器连接后,我们对玩家进行身份验证,以便我们可以将他们连接到一个标识。
启动 Pirate Panic 时,您可能会注意到您已自动经过身份验证并被分配了一个用户名。这种类型的无缝身份验证是设备身份验证,它创建与运行游戏的设备(例如手机或计算机)相关联的帐户。
在 Unity 中,完成设备身份验证的方法是获取设备 ID 并将其传递到 AuthenticateDeviceAsync
:
1
2
string deviceId = SystemInfo . deviceUniqueIdentifier ;
session = await client . AuthenticateDeviceAsync ( deviceId );
如面向 WebGL 构建,您可能需要使用 System.Guid.NewGuid().ToString()
而非 deviceUniqueIdentifier
。
身份验证完成后,玩家加入会话 ,这表示玩家登录的一个时间段。参见会话 ,了解详情。
会话对象可让我们主要通过 Socket
和 Account
对象,发出请求和访问用户信息:
1
2
3
var socket = client . NewSocket ( useMainThread : true );
await socket . ConnectAsync ( session );
account = await client . GetAccountAsync ( session );
在 Pirate Panic 中,client
、socket
、account
和 session
属性保存在 GameConnection
对象中。以后任何一次访问 _connection
,记住这指的是这些属性。
您可以根据需要组织服务器连接,只要确保它可以被其他类访问。
Facebook 身份验证
# 设备身份验证使玩家可以轻松地直接进入游戏,但是将帐户链接到设备意味着如果设备丢失或重置,则帐户将丢失。通过外部社交服务提供商(如 Facebook)连接到用户帐户,可以缓解此问题并获取其他用户信息。
如果您克隆了项目存储库,Pirate Panic 代码中包含了 Facebook SDK。如您启动了自己的项目,您需要
获取 SDK 。
将 Facebook SDK 加入场景脚本,并按如下方式对其进行初始化:
1
2
3
4
5
6
7
8
using Facebook.Unity ;
..
private void InitializeFacebook () {
FB . Init (() =>
{
FB . ActivateApp ();
});
}
然后,以下片段处理登录:
ProfileUpdatePanel.cs
1
2
3
4
5
6
7
8
9
10
11
private void LinkFacebook ()
{
List < string > permissions = new List < string >();
permissions . Add ( "public_profile" );
FB . LogInWithReadPermissions ( permissions , async result =>
{
string facebookToken = result . AccessToken . TokenString ;
await _connection . Client . AuthenticateFacebookAsync ( facebookToken );
});
}
您可以选择将 LinkFacebook
绑定到 Connect Facebook 按钮,以便玩家可以选择何时登录,而不是被迫立即登录。
此处我们给出了 public_profile
权限,因此 Nakama 可以访问用户名或个人资料图片等基本的用户信息。您还可以添加其他权限和功能,这些都包含在 Facebook SDK 文档 中。
登录 Facebook,将自动将玩家的 Facebook 好友添加到其游戏内好友 列表。
初始化新玩家
# 在玩家有了登录的方法后,接下来是设置初始玩家信息,以便他们可以开始添加好友、收集宝石、完成任务或其他需要不断存储用户数据的内容。
这可以使用 register 挂钩 ,在服务器端完成。对于每个身份验证方法,有一个不同的挂钩。例如,因为我们设置了设备和 Facebook 身份验证,我们应当使用 registerAfterAuthenticateDevice
和 registerAfterAuthenticateFacebook
。
我们将一个函数绑定到它们,触发此挂钩时,函数即运行:
main.ts
1
2
3
4
5
6
7
8
9
10
11
initializer . registerAfterAuthenticateDevice ( afterAuthenticateDeviceFn );
const afterAuthenticateDeviceFn : nkruntime.AfterHookFunction < nkruntime.Session , nkruntime.AuthenticateDeviceRequest > = function ( ctx : nkruntime.Context , logger : nkruntime.Logger , nk : nkruntime.Nakama , data : nkruntime.Session , req : nkruntime.AuthenticateDeviceRequest ) {
afterAuthenticate ( ctx , logger , nk , data );
if ( ! data . created ) {
return ; // Account already exists.
}
...
// Player initialization goes here. Write initial stats, add items to inventory, etc.
}
会话令牌
# 出于安全原因,在您在 Nakama 配置 中定义的时间段后,玩家会话将自动过期。为了避免强制玩家不断重新登录,我们可以设置一个方法,在旧会话即将到期时自动请求新会话。
其实现方法是将身份验证令牌 保存到客户端,定期将其传回服务器,以请求新的令牌。
令牌有两种:
访问令牌 :将客户端标识告诉服务器,让服务器信任此客户端。刷新令牌 :用于请求新的访问令牌。通过 Nakama,我们可以用 client
对象通过 SessionRefreshAsync
请求新的令牌:
Scene01MainMenuController.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
string authToken = PlayerPrefs . GetString ( "nakama.authToken" , null );
string refreshToken = PlayerPrefs . GetString ( "nakama.refreshToken" , null );
session = Session . Restore ( authToken , refreshToken );
// Check whether a session is close to expiry.
if ( session . HasExpired ( DateTime . UtcNow . AddDays ( 1 ))) {
try {
// get a new access token
session = await client . SessionRefreshAsync ( session );
} catch ( ApiResponseException ) {
// get a new refresh token
session = await client . AuthenticateDeviceAsync ( deviceId );
PlayerPrefs . SetString ( "nakama.refreshToken" , session . RefreshToken );
}
PlayerPrefs . SetString ( "nakama.authToken" , session . AuthToken );
}
此处我们使用 Unity 的内置 PlayerPrefs
引擎存储访问令牌,并将令牌分别刷新到 nakama.authToken
和 nakama.refreshToken
。
如果会话离到期还有不到一天,脚本将尝试用 SessionRefreshAsync
请求新的访问令牌。如果刷新令牌无效,这将失败,我们将需要从头开始重新进行身份验证。
下一主题
# 好友和聊天
Related Pages