-
Notifications
You must be signed in to change notification settings - Fork 577
AccountServer
此章节介绍如何使用账号登陆服务器
目前只提供IIS站点方式部署,去掉d=xxx格式的参数(与游戏参数不同之处)。
分为游客操作,正常用户操作和第三方账号(小米、当乐等账号),与账号服务器详细的通讯指令见本节的1.3。
已实现第三方SDK登录有:uc,小米,魅族,当乐,360。其他第三方登录实现,请在ZyGames.Framework.Game.Sns中自行实现。
游客账号:只能在单台手机设备上登录的,不需要用户的密码,识别用户手机的唯一IMEI编号,存在丢账号的风险(卸载包时容易丢失),当用户被全密码后可以转为正常的用户;正常用户可以在多台设备上登录。
-
游客操作:步骤
- a) 检查客户端是否有存储游客的账号,如果存在发送
Login
指令到账号服务器登录,否则跳到e步骤注册账号; - b) 账号服务器检查游客的身份,如果身份认证成功,返回一个授权的身份认证凭据
Token
给客户端; - c) 客户端需要记住它并使用此
Token
与游戏服务器进行交互,游戏服务器接收到Token
会向账号服务器发送Validate
指令验证有较性; - d) 账号服务器检查游客的身份失败,客户端提示用户"登录失败";
- e) 客户端自动注册游客的账号;
- f) [可选]需要先发送
Passport
指令获取自动分配的账号与随机密码(使用自定义的账号可跳过) - g) 客户端提供账号与随机密码,以及imei参数向账号服务器发送
Login
指令,快速注册并返回一个授权的身份认证凭据Token
给客户端,接着跳到c步骤; - h) 如果游客需要转为正常用户,需要发送
Password
指令补全密码,修改成功后就可以使用账号与密码的方式登录;
- a) 检查客户端是否有存储游客的账号,如果存在发送
-
正常用户操作:步骤
- a) 客户端输入账号和密码,发送
Login
指令到账号服务器登录; - b) 账号服务器检查游客的身份,如果身份认证成功,返回一个授权的身份认证凭据
Token
给客户端; - c) 客户端需要记住它并使用此
Token
与游戏服务器进行交互,游戏服务器接收到Token
会向账号服务器发送Validate
指令验证有较性; - d) 账号服务器检查游客的身份失败,客户端提示用户重新输入,或跳到注册界面;
- e) 客户端注册正常用户账号;
- f) [可选]需要先发送
Passport
指令获取自动分配的账号与随机密码(使用自定义的账号可跳过) - g) 客户端提供用户输入账号与密码后,并向账号服务器发送
Regist
指令,注册成功后返回一个授权的身份认证凭据Token
给客户端,接着跳到c步骤;
- a) 客户端输入账号和密码,发送
-
第三方账号接入:步骤
- a) 客户端与服务端协商确定第三方的渠道的编号
RetialID
,如'1001'; - b) 客户端使用第三方的SDK,登录第三方账号平台,获取账号ID:
RetialUser
与身份凭据:RetailToken
; - c) 客户端提供参数:
RetailID
,RetialUser
,RetailToken
向账号服务器发送Login
指令; - d) 账号服务器接到后,向第三方账号平台发送
RetailToken
验证有效性,如果失败返回给客户端提示用户“登录失败”; - e) 如果验证成功,根据参数
RetailID
,RetialUser
检查是否存在自己平台的账号,如果不存在,自动注册并分配一个账号与之绑定 - f) 存在自己平台的账号,返回一个授权的身份认证凭据
Token
给客户端; - g) 客户端需要记住它并使用此
Token
与游戏服务器进行交互,游戏服务器接收到Token
会向账号服务器发送Validate
指令验证有较性;
- a) 客户端与服务端协商确定第三方的渠道的编号
功能后续版本实现
使用Http的get方式请求,服务器以Handler参数分发请求(同游戏服务器的ActionId,这里可以是String类型),其中Sign签名参数必须要放在结尾(签名方式下文有详细介绍)。
http://{Url}/?Handler={应用程序处理名称}&{query}&Sign=xxxxxx
**注意** 所有的Pwd在传输的时候,必须经过加密处理(客户端SDK已经提供)。示例为了方便读者查看,都用明文书写,请实际应用的时候注意。
- 示例
http://pass.scutgame.com/?Handler=Regist&MobileType=1&Pid=Z17465&Pwd=1234567&IMEI=xxxxxx&ScreenX=960&ScreenY=860&RetailID=0000&sign=a53c02c3189d59c3ef5a4c0d0c96faec
使用Json格式响应请求,消息结构如下:
{
"StateCode": "{错误码}",
"StateDescription": "{错误描述}",
"Vesion": "{版本}",
"Handler": "{请求的应用程序处理名称}",
"Data":
{
"{这里是业务层的数据对象}"
}
}
- 示例
{
"StateCode": 0,
"StateDescription": "",
"Vesion": "1.0",
"Handler": "Validate",
"Data":
{
"Token": "3074e807e73c4a899facb455aab1725e",
"PassportId": "Z17465",
"UserId": 1973013
}
}
- 0:电脑PC
- 1:iPod
- 2:iPad
- 3:iPhone(越狱)
- 4:Phone
- 5:Android
- 6:Mac
- 7:WindowsPhone7
- 8:Unknow未知
- 0: OK,成功的
- 100:服务器异常
- 101:签名错误
- 102:无处理程序
- 103:密码错误
- 105:登录凭证无效
- 106: 登录凭证过期
客户端是不允许自定义账号的,统一由登录服务器系统自动分配账号。
应用程序处理名称:Passport
-
请求参数
- IMEI:String类型,手机设备识别码,不可以为空;如果上次有注册过,返回上次使用的账号
-
响应参数
- PassportId:String类型,系统分配账号,如果已经使用IMEI获得过的,下发上次的账号
- Password:String类型,如imei已绑定(注册)帐号,则返回帐号的密码。否则,随机生成的密码(加密后的)
-
示例
请求:
http://pass.scutgame.com/?Handler=Passport&IMEI=00:02:32:65&sign=2bcc51b165368e139111914e12864a89
或
http://pass.scutgame.com/?Handler=Passport&IMEI=&sign=c519d93c5acb9c074086bc9df0c23285
响应:
{
"StateCode": 0,
"StateDescription": "",
"Vesion": "1.0",
"Handler": "Passport",
"Data":
{
"PassportId": "Z17465",
"Password": "564613"
}
}
应用程序处理名称:Login
-
请求参数
- MobileType:【必传】Int整型,手机类型
- Pid:【必传】String类型,获取账号接口下发的账号,第三方登录可以为空
- Pwd:【必传】String类型,获取账号接口下发的密码,第三方登录可以为空
- IMEI:String类型,手机设备识别码,可以为空;不为空时如果上次有注册过,返回上次使用的账号
- ScreenX:Int整型,手机屏幕宽度
- ScreenY:Int整型,手机屏幕高度
- RetailID:String类型,客户打包的渠道编号,服务端与客户端协商确定
- IsCustom:Bool类型,账号使用自定义的,True为启用;
- RetialUser:String类型,第三方登录的账号ID
- RetialToken:String类型,第三方登录的账号身份凭证
-
响应参数
- Token:String类型,登录授权成功获得的凭证,有效期(24H)
- UserID:Int整型,用户的唯一编号
-
示例
请求:
http://pass.scutgame.com/?Handler=Login&MobileType=0&Pid=Z17465&Pwd=564613&IMEI=&ScreenX=&ScreenY&RetailID=&sign=c792a4eb8a7761524ea6e512f0efc939
响应:
{
"StateCode": 0,
"StateDescription": "",
"Vesion": "1.0",
"Handler": "Login",
"Data":
{
"Token": "3074e807e73c4a899facb455aab1725e",
"UserID": 1395265
}
}
注册成功可直接获得授权成功的凭证,提供快速注册的方式。
应用程序处理名称:Regist
-
请求参数
- MobileType:【必传】Int整型,手机类型
- Pid:【必传】String类型,获取账号接口下发的账号
- Pwd:【必传】String类型,获取账号接口下发的密码
- IMEI:String类型,手机设备识别码,可以为空
- ScreenX:Int整型,手机屏幕宽度
- ScreenY:Int整型,手机屏幕高度
- RetailID:String类型,客户打包的渠道编号
- IsCustom:Bool类型,账号使用自定义的,True为启用;
-
响应参数
- Token:String类型,登录授权成功获得的凭证,有效期(24H)
- UserID:Int整型,用户的唯一编号
-
示例
请求:
http://pass.scutgame.com/?Handler=Regist&MobileType=0&Pid=Z17465&Pwd=564613&IMEI=&ScreenX=&ScreenY&RetailID=&sign=7ca97cdfa7460da2ff164c0cc8883768
响应:
{
"StateCode": 0,
"StateDescription": "",
"Vesion": "1.0",
"Handler": "Regist",
"Data":
{
"Token": "3074e807e73c4a899facb455aab1725e",
"UserID": 1395265
}
}
应用程序处理名称:Password
-
请求参数
- PassportId:【必传】String类型,账号
- Password:【必传】String类型,密码
-
响应参数
- 空
-
示例
请求:
http://pass.scutgame.com/?Handler=Password&PassportId=Z17465&Password=123456&sign=547bc476c3ab068203b76f9362eebd27
响应:
{
"StateCode": 0,
"StateDescription": "",
"Vesion": "1.0",
"Handler": "Password",
"Data":
{
}
}
应用程序处理名称:Validate
-
请求参数
- Token:【必传】String类型,登录凭证
-
响应参数
- Token:登录凭证
- UserId:Int整型,用户的唯一编号
- PassportId:String类型,账号
-
示例
请求:
http://pass.scutgame.com/?Handler=Validate&Token=3074e807e73c4a899facb455aab1725e&sign=370114a38837acd248a3c3eb79d8b4a6
响应:
{
"StateCode": 0,
"StateDescription": "",
"Vesion": "1.0",
"Handler": "Validate",
"Data":
{
"Token": "3074e807e73c4a899facb455aab1725e",
"UserId": 1395265,
"PassportId": "Z17465"
}
}
流程步骤如下:
-
在IIS中新建网站名称(如:pass.scutgame.com);
-
设置应用程序池为 .NET Framework4.0版本;
-
修改Web.config配置文件,设置Token缓存到Redis位置及账号数据库的地址,如下配置:
<appSettings> <add key="Product.SignKey" value=""/> <add key="Product.ClientDesDeKey" value="j6=9=1ac"/> <add key="Redis.Host" value="127.0.0.1:6379" /> <add key="Redis.Db" value="0" /> </appSettings> <connectionStrings> <add name="SnsCenter" providerName="SqlDataProvider" connectionString="Data Source=localhost;Database=SnsCenter;Uid=sa;Pwd=123" /> </connectionStrings> <system.webServer> <defaultDocument> <files> <add value="Default.ashx"/> </files> </defaultDocument> </system.webServer>
配置提示:
- defaultDocument结点是配置网站的默认方法地址,
- 客户访问时只需要(如:http://pass.scutgame.com/?Handler=Login)这样访问,
- 否则需要写完整直址,(如:http://pass.scutgame.com/Default.ashx?Handler=Login)
-
打开IE输入http://pass.scutgame.com/?Handler=Login测试,有显示Json格式数据表示成功,(可能会有弹出下载提示,下载后打开也是Json数据)
2.1 第三方SDK登录支持
config配置 新建“Game.config.xml”文件,如下配置:
<?xml version="1.0" encoding="utf-8" ?>
<GameConfig>
<login>
<!--id:渠道号,type:处理类, args:类的构造参数-->
<add id="0001" type="Login36you" args="Pid,Pwd,DeviceID"/>
</login>
<sdkChannel>
<channel36you>
<channel name="0001" appId="123" appKey="123" appSecret="123"/>
</channel36you>
</sdkChannel>
</GameConfig>
客户端的连接方式:先登录 -- 选区(或服) -- 登录游戏服
流程步骤如下:
- 客户端输入账号密码后,将数据提交到账号登录服务器(pass.scutgame.com),请求参数同上说明的格式接入
- 拿到登录服务器提供的授权凭证(Token)后,再请求分服中心服务器(dir.scutgame.com)获得所有的服务器列表信息;
- 选择其中一个服务器,接着需要将token通过请求参数提交给游戏服,较验通过进入游戏。
调用示例
客户端拼接字串,参数d的值需要UrlEncode编码,请求参数的格式参见如何定义客户端与服务端通讯协议
参数拼接字串
MsgId=0&Sid=&Uid=0&ActionID=1004&St=&Token=3074e807e73c4a899facb455aab1725e&MobileType=1&IMEI=&RetailID=&ScreenX=&ScreenY=&ClientAppVersion=
签名以参数拼接字串
+签名Key
做MD5加密,签名后做为参数名sign的值,再与参数拼接字串
拼接
MsgId=0&Sid=&Uid=0&ActionID=1004&St=&Token=3074e807e73c4a899facb455aab1725e&MobileType=1&IMEI=&RetailID=&ScreenX=&ScreenY=&ClientAppVersion=&sign=e8eda14d6037ddf1a5b85a0d4189f068
接着再对它进行UrlEncode编码,将整个串做为d参数的值提交给服务器
MsgId%3D0%26Sid%3D%26Uid%3D0%26ActionID%3D1004%26St%3D%26Token%3D3074e807e73c4a899facb455aab1725e%26MobileType%3D1%26IMEI%3D%26RetailID%3D%26ScreenX%3D%26ScreenY%3D%26ClientAppVersion%3D%26sign%3De8eda14d6037ddf1a5b85a0d4189f068
最终字串结果
?d=MsgId%3D0%26Sid%3D%26Uid%3D0%26ActionID%3D1004%26St%3D%26Token%3D3074e807e73c4a899facb455aab1725e%26MobileType%3D1%26IMEI%3D%26RetailID%3D%26ScreenX%3D%26ScreenY%3D%26ClientAppVersion%3D%26sign%3De8eda14d6037ddf1a5b85a0d4189f068
提示:
- 使用Scut的通讯格式,可以通过协议工具自动生成调用代码;
- 自定格式参见如何定制客户端与服务端的通讯协议;
签名方式
- 签名Key:要与游戏服务器的Config配置文件的一致
客户端在账号登录服务器拿到的Token连接到游戏服务器,游戏服务器需要连接到登录服务器较验Token是否有效。
流程步骤如下:
-
修改在游戏服务器LoginAction的子类接口(Action1004)的较验方法,如下:
public class Action1004 : LoginAction { /// <summary> /// 授权凭证 /// </summary> private string _token; /// <summary> /// 末填写则默认为1.0版本 /// </summary> private string _clientAppVersion; public Action1004(ActionGetter actionGetter) : base((short)1004, actionGetter) { } public override bool GetUrlElement() { if (httpGet.GetString("Token", ref _token) && httpGet.GetEnum("MobileType", ref MobileType) && httpGet.GetString("IMEI", ref DeviceID) && httpGet.GetString("RetailID", ref RetailID)) { httpGet.GetWord("ScreenX", ref ScreenX); httpGet.GetWord("ScreenY", ref ScreenY); httpGet.GetString("ClientAppVersion", ref _clientAppVersion); return true; } return false; } protected override ILogin CreateLogin() { //return new AccountServerRedisLogin("127.0.0.1:6379", 0, _token); //6.7.9.11版本优化支持连Redis较验检查 return new AccountServerLogin(GameEnvironment.Setting.AccountServerUrl, _token, DeviceID); } protected override void DoLoginFail(ILogin login) { ErrorCode = Language.Instance.ErrorCode; ErrorInfo = Language.Instance.ServerBusy; } }
-
修改GameServer.exe.config配置,增加登录服务器的地址,如下:
<appSettings> <add key="AccountServerUrl" value="http://pass.scutgame.com"/> </appSettings>