木匣子

Web/Game/Programming/Life etc.

手游登录模块开发流程分析

最近在研究服务端,打算从最基本的系统着手开始,看看客户端与服务端具体的模块是如何工作的。我最先想到的是登录模块,于是翻看了网上的一些教程以及当前的工作项目,学到了很多东西,但是发现了一些问题,在这里整理出来。

At the beginning

很多手游团队开始开发游戏的时候,往往会先做主要的游戏系统,而把登录模块放到最后来做。因为后期需要接入接运营平台的 SDK,而用户登录与注册往往直接由 SDK 提供,所以游戏系统只需要一个简单的认证接口就行了。在开发期间,登录模块通常看起来是这样:

login-dev.png

为了简单起见,开发团队通常直接使用一个编辑框输入指定的 uid 创建并登录游戏。这个 uid 在后期由 SDK 登录后提供。而这样做可以在开发阶段为创建账号提供很大便利。

Add SDK

在开发的后期,从运营商那里获得 SDK 然后接入游戏系统。帐号的注册及创建流程都内置在 SDK 内了,最后只需要从 SDK 那里获得玩家的 uid 就可以完美地接入之前的游戏系统了!

是的很多团队都以为这样就大功告成了,但是请千万不要这样做:

login-with-sdk.png

直接使用之前的系统会有什么问题?用户在 SDK 中注册了帐号,并获得了属于自己的 uid ,然后用这个 uid 登录游戏也没什么不妥对吧——当然在 release 版的游戏中,uid 对玩家来说是透明的,玩家不知道它们的存在。看似很安全,但是永远不要忘了那句忠告:

不要完全信任客户端传来的数据

The Hacker

林子大了什么鸟都有,无论你做了多大努力,你都无法保证你的客户端不会被逆向,或者网络通讯被窃听甚至修改。

玩家通过 SDK 获得的 uid 只能确保客户端知道玩家的身份;而客户端将这个 uid 传递给游戏服务器,并不能 100% 保证服务器得到的 uid 属于这个用户,它可能已经被篡改了:

login-evil.png

那我们应该怎么做才能保证即使客户端被逆向,坏玩家也无法侵犯他人的游戏帐号,并且不需要开发自己的帐号系统?

OAuth 2.0

现在大多数的 SDK 已经实现以 OAuth 2.0 为基础的第三方登录系统了。OAuth 2.0 也正是为了解决这样的情况而被发明的。如果你还不理解 OAuth 2.0 的工作机制,可以读一下阮一峰的《理解 OAuth 2.0》

于是我们只需要对登录模块进行一些小的改动,就可以应付上面的情况:

login-the-right-way.png

除了从 SDK 获得 uid,我们还需要获得认证令牌(token)——由 SDK 提供的用户凭证,出示它就可以表明你获得了用户的许可,以便可以向第三方服务提供商索取资料。

然后客户端将 uid 与 token 一起提交给游戏服务端。服务端使用 uid 和 token 向 SDK 的资源服务器提供的 API 发起用户认证请求,来检查这个 uid 确实属于该用户,然后完成游戏登录。

多个 SDK

有些项目往往需要接入多个 SDK,所以可以增加一个 platform 参数,让游戏服务端知道玩家从哪个 SDK 登录,以便向正确的 SDK 资源服务器发起认证。

Admin SDK

做了这样的改动后,原来开发环境通过在编辑框输入 uid 的登录方式就不起作用了。管理员也没办法像原来那样方便地登录任意玩家的帐号了。不过我们肯定不希望因为便利性而牺牲安全性对吧。

我们可以对系统做一些小改动,可以将管理员登录封装成 SDK 的形式,也可以在外部或得管理员权限,以 token 的形式填入客户端,这样就可以兼容上面提到的流程了。

login-admin.png

More

越来越多的手游采用这种非常依赖 SDK 的开发方式,但是一旦 SDK 出现网络故障,就可能导致玩家无法进入游戏。所以我觉得拥有一个自建帐号系统还是很有必要的。关于登录模块,还有很多可以思考的部分,例如游客登录、帐号绑定等需求。有时候再慢慢研究。