手游的登陆流程研究

前言

移动端游戏与传统的端游在登录流程上还是有一些差异性的。

  1. 大部分的偏单机游戏(有联网玩法)的做法是第一次登录时创建昵称,但是不用设置密码,因为用了设备的 id 作为了登录凭证。如果换一个手机,相当于重新创建了个帐号。如果在手机上删除了这个应用,再重新安装,这个有两种选择:一种是重新创建帐号;或者保留原始数据不变(前提是应用的数据文件没有被删除)。

  2. 如果是 MMOG 这种纯网游形式的手游,那基本就和端游没什么区别。第一次进游戏就要求创建帐号,将来登录都是以帐号为依据,因为所有的数据都存于服务器,所以换手机登录,也不受影响。

关于 Kerberos

不管 MMOG 或者是弱联网游戏,总会有登录游戏的过程。具体登录的流程,可以借鉴 Kerberos。

Kerberos 是一个网络认证协议,源自希腊神话中的角色“地域三头犬”。

Kerberos 的设计目标是通过密钥系统,为客户端/服务器提供强大的认证服务。

如果适用在网络游戏中,大概流程应该如下:

  1. client 发请求到登录服务器,要求得到游戏服务器的证书;
  2. 登录服务器生成一份证书,包括:一份 session key,也就是将来通信的加密密钥;一份 login code,client 登录游戏服务器凭据。并将这份证书发送至游戏服务器和 client。
  3. client 根据 login code 登录游戏服务器,通信包通过 session key 加解密。

简单登录流程

暂时在我们的游戏中,选择了将帐号的相关业务直接加入到登录服务中,简单化处理,具体的流程如下面(设定客户端在登录之前都已经自动更新至最新版本):

  1. 登录请求: client -> loginsvr 请求登录,带上用户名和密码(也可能是机器码),这里的加密只能是依赖服务器与客户端事前约定好的密钥来加密。
  2. 创建账户: 如果是第一次登录,需要根据游戏的需求生成用户名密码,或者由客户端创建账户密码,这中间有若干次的交互过程。
  3. 生成证书: loginsvr 登录服务器在db中检验用户名和密码之后,生成证书(session key + login code + client ip)。
  4. 选择大区:
    • loginsvr -> gamesvr notify login session
    • loginsvr -> client response login
    • 选择大区时,如果是服务器自动选择,直接回复服务器地址,并将证书通知到对应的服务器
    • 如果需要客户端手工选择,那么这里就要下发游戏服务器的列表,与客户端做一次交互之后,再将证书下发到对应的服务器,等待客户端登录;
  5. 登录游戏
    • client -> gamesvr request login
    • gamesvr -> client response login
    • 客户端登录游戏服务器,服务器解密后校验 login code,并回复。
  6. 退出游戏
    • 如果客户端退出游戏服务器,再次登录时,需要重复 1-4 的流程。
    • 游戏服务器中登录证书的有效期,就是从收到 loginsvr 的通知,到客户端登录完成的时间,有点类似现在的网上银行,通知密码发送到手机,使用后就失效。

补充完善

一直都感觉还是上面的流程多少有些不安全,今天阅读了云风大牛的blog

其中有段话:“用户认证过程自然不能传送用户密码的全部信息,这跟密码是否加密无关。简单的安全措施是先由登陆服务器发送一个随机串给用户,用户把这个字符串同自己的密码连接起来,并 md5 以后传回服务器做验证。(这里用 md5 指代一种特定的不可逆 hash 算法)”.

非常赞同这个观点,并修改之前步骤 1 中的不安全的因素,改为由登录服务器下发 loginkey 之后,再由客户端请求登录,下发 loginkey 的同时,也可以通知客户端后续与 loginsvr 通信包加解密的密钥;

关于这样子带来的性能问题:

  1. 只要用户登录,loginsvr 就下发 login-key,可能会造成性能的损失。此处目前我们游戏服务器中,网络模块的连接有一个校验的过程,模仿了 web-socket 的三次握手过程,所以恶意连接带来的性能损耗,可以有一定程度上的减轻,但是不能完全避免.
  2. loginsvr 计算 md5 的性能损耗,这个几乎可以忽略.
  3. 最后,一般的 MMOG,loginsvr 会是一个无状态的集群,平行扩展很方便.

参考文章