航行日志

登录服务相关设计

登录服务设计

服务端启动原理:

首先读取同目录下配置文件

{
    "",
    "server info list":[
        {
            "server hub":"",
            "ip":0.0.0.0,
            "port":4888,
            "update path":"D:\\App\\update",
            "upload path":"D:\\App\\upload",
            "database server":"192.168.0.210",
            "database name":"App001",
            "database user":"sa",
            "database password":7jbjztJqo33LNWOfY8tcVQ==
        },
        {
            "server hub":"DEMO",
            "ip":0.0.0.0,
            "port":4889,
            "update path":"D:\\App\\update",
            "upload path":"D:\\App\\upload",
            "database server":"192.168.0.210",
            "database name":"App001",
            "database user":"sa",
            "database password":7jbjztJq233LNWOfY8tcVQ==
        },
        {
            "server hub":"TEST",
            "ip":0.0.0.0,
            "port":4890,
            "update path":"D:\\App\\update",
            "upload path":"D:\\App\\upload",
            "database server":"192.168.0.210",
            "database name":"App001",
            "database user":"sa",
            "database password":7jbjztJq344LNWOfY8tcVQ==
        },
    ]
}

根据配置,启动对应服务。

服务端:

流程如下,收到请求后,检查公司别是否存在;如果成功,根据UseDomain(域登录),进行用户名检查,看是否在该公司有权限。

A.域登录的话,首先检查域名称是否在”用户权限设定“中进行设置
B.账户登录,检查数据库帐户表,密码符合则登录成功。

当登录成功,服务端返回认证票据,同时,在服务端保存该票据,有效时间为2小时。(有效时间可以根据具体使用调整)

CREATE TABLE [dbo].[LogonTicket] (
    [UserId] [nvarchar](20)   NOT NULL PRIMARY KEY ,
    [Ticket] [nvarchar](1024) NOT NULL ,
    [Stamp]  [datetime] default GETDATE()
)  ON [PRIMARY]
GO        

票据格式如下(未来考虑加入权限内容)

ticket = { VER , AL , USERID , COMPANY , VALIDDATE , SALT , [HASH( VER , AL , USERID , VALIDDATE , SALT)] }

            VER:版本 1.0
            AL:MD5
            SALT:混淆字符串
            合成BASE64码串

Launcher读取到该Ticket后,以 /t参数传入 APP.exe,进入后,以该ticket至登录服务器验证。通过后,对ticket解码,读取相关权限,载入对应菜单。

请求Request格式

{
    "Client":"Launcher",
    "Command":"Login",
    "Company":"A",
    "UserId":"john@sina.com.cn",
    "Password":0xF234B5E9,         // 加密密码
    "UseDomain":True               // 是否以域名登录,需在
} 

回应Response格式:

{
    "State":230,                    // 登录成功
    "Ticket":0xD2967BE93A93A6748C9  // 验证票据
}

{
    "State":430,                    // 登录失败
    "Message":"Company invalid"     // 错误讯息
}

失败码:

430 无此公司 Company invalid
431 无此登录用户 User invalid
432 登录用户在该公司无权限 Users in the company without permission
433 登录密码错误 Login password mistake
434 未绑定ERP系统账户 This account is not binding account in ERP system
435 该账户已在其他地方登录 This account has been login in other places
436 登录服务器繁忙,请稍后再试! The login server is busy, please try again later. 
437 域登录失败 Domain login failed
438 服務器資料庫未連接或連接失敗! Server database not connected or connection failure
439 该账户未启用 This account is not enabled

当验证登陆成功后,取Ticket传入,主程序内部开启一个cmdClient,发送包

Request格式

{
    "Client":"APP-Client",
    "Command":"Verify",
    "Ticket":0xD2967BE93A93A6748C9  // 验证票据
} 

回应Response格式:

{
    "State":220,                    // 登录成功
    "Command":"Verify",
    "Message":"Verify success"      // 登录验证成功
}

服务端记录该链接的IP地址,用户名等讯息。

登出服务:
客户端发送登出请求,服务端收到登出请求后,对该账户所有登录客户端发送登出消息,客户端检测到登出请求后进行登出动作。

客户端登陆流程:
客户端首先请求主服务端口对应实例

发送请求

{
    "Client":"Launcher",
    "Command":"QueryHub",
    "Hub":""                
} 
或
{
    "Client":"Launcher",
    "Command":"QueryHub",
    "Hub":"DEMO"                
} 

收到后回应

{
    "State":211,
    "Command":"QueryHub",
    "Hub":"", 
    "Port":4888 
}
或
{
    "State":211,
    "Command":"QueryHub",
    "Hub":"DEMO", 
    "Port":4889
}

失败后返回
{
    "State":411,
    "Command":"QueryHub",
    "Hub":"", 
}