You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

51 lines
1.7 KiB
Lua

local socket = require 'socket'
local crypt = require "skynet.crypt"
local function encode_token(token)
return string.format("%s@%s:%s:%s", crypt.base64encode(token.user), crypt.base64encode(token.worldId),
crypt.base64encode(token.pass), crypt.base64encode(token.pf))
end
local token = {
pf = '1010',
user = 'teefe',
pwd = '123456789',
worldId = 1,
}
return function(login_host, login_port)
local sock = socket.connect(login_host or '127.0.0.1', login_port or 9527)
local challenge = crypt.base64decode(sock:receive('*l'))
local clientkey = crypt.randomkey()
sock:send(crypt.base64encode(crypt.dhexchange(clientkey)) .. '\n')
local line = crypt.base64decode(sock:receive '*l')
local secret = crypt.dhsecret(line, clientkey)
local hmac = crypt.hmac64(challenge, secret)
-- 5. 回应服务器的握手挑战码,确认握手正常
sock:send(crypt.base64encode(hmac) .. '\n')
-- 6. DES加密发送 token串
local etoken = crypt.desencode(secret, encode_token(token))
sock:send(crypt.base64encode(etoken) .. '\n')
-- 服务器解密后调用定制的auth和login handler处理客户端请求
-- 7. 从服务器读取 登录结果: 状态码 和subid
local result = sock:receive '*l'
local code = tonumber(string.sub(result, 1, 3))
assert(code == 200, "auth error:" .. tostring(code))
sock:close()
local substr = crypt.base64decode(string.sub(result, 5))
local ip, port, uid, subid = substr:match("([^:]+):([^:]+)@([^@]+)@(.+)")
return {
ip = ip,
port = port,
uid = uid,
worldId = token.worldId,
secret = secret,
subid = subid,
}
end