local config = require("fwutils.config") local codec = require("fastweb.codec") local utils = require("utils") local cjson = require("cjson") local redis_pool = require("redis.pool") local mysql_pool = require("mysql.pool") local M = {} local function make_key(id,token) if type(id) == "number" then id = string.format("%d",id) end return config.server_id.."_token_"..id.."_"..token end M.__delete_mysql_token = function(token,conn) local update = conn:update() update:table("fw_token") update:set("delete_time=NOW()") update:where_str("`fw_token`.`token`","=",token) update:where_expression("AND `fw_token`.`delete_time` IS NULL") local d = update:exec() return d == 1 end M.__list_mysql_token = function(role_id,id,conn) local select = conn:select() select:table("fw_token") select:where_i32("`fw_token`.`role_id`","=",role_id) select:where_i32("`fw_token`.`custom_id`","=",id) select:where_expression("AND `fw_token`.`delete_time` IS NULL") local d = select:query():table() return d end M.__parse_token = function(token) if token == nil or token == "" then return false,"token is required" end local token_data = codec.aes_de(config.token.key,utils.hex_to_bytes(token),config.token.algorithm,config.token.mode) if token_data == nil or token_data == "" then return false,"token is invalid(a)" end local token_data_json = cjson.decode(utils.hex_to_bytes(token_data)) if token_data_json == nil or token_data_json.id == nil or token_data_json.id <= 0 then return false,"token is invalid(no id)" end return true,token_data_json end M.get = function(token) -- 解析TOKEN local result,token_data_json = M.__parse_token(token) if not result then return false,token_data_json end -- 获取TOKEN数据 local conn = redis_pool.new(_G[config.db.redis_pool_name]):get() local data = conn:get(make_key(token_data_json["id"],token)) if data ~= nil and data ~= "" then return true,cjson.decode(data) end return false,"token is invalid" end M.set = function(token,data) -- 解析TOKEN local result,token_data_json = M.__parse_token(token) if not result then return false,token_data_json end if data == nil then return false,"data is required" end local conn = redis_pool.new(_G[config.db.redis_pool_name]):get() conn:setex(make_key(token_data_json["id"],token),config.token.expire,cjson.encode(data)) return true end M.del_by_id = function(id) if id == nil or id <= 0 then return false,"id is required" end local conn = redis_pool.new(_G[config.db.redis_pool_name]):get() local conn_mysql = mysql_pool.new(_G[config.db.mysql_pool_name]):get() local keys = conn:keys(config.server_id.."_token_"..string.format("%d",id).."_*") for _,key in ipairs(keys) do conn:del(key) M.__delete_mysql_token(key,conn_mysql) end return true end M.del_by_id_ex = function(server_id,id) if server_id == nil or server_id == "" then return false,"server_id is required" end if id == nil or id <= 0 then return false,"id is required" end local conn = redis_pool.new(_G[config.db.redis_pool_name]):get() local conn_mysql = mysql_pool.new(_G[config.db.mysql_pool_name]):get() local keys = conn:keys(server_id.."_token_"..string.format("%d",id).."_*") for _,key in ipairs(keys) do conn:del(key) M.__delete_mysql_token(key,conn_mysql) end return true end M.del_by_token = function(token) -- 解析TOKEN local result,token_data_json = M.__parse_token(token) if not result then return false,token_data_json end local conn = redis_pool.new(_G[config.db.redis_pool_name]):get() local conn_mysql = mysql_pool.new(_G[config.db.mysql_pool_name]):get() conn:del(make_key(token_data_json["id"],token)) M.__delete_mysql_token(token,conn_mysql) return true end M.create = function(id,role_id,data) if id == nil or id <= 0 then return false,"id is required" end local key_data = { id = id, create_time = fw.now_msec() } local token = codec.aes_en(config.token.key,cjson.encode(key_data),config.token.algorithm,config.token.mode) if M.set(token,data) == false then return false,"create token failed" end -- 保存TOKEN到MYSQL local conn = mysql_pool.new(_G[config.db.mysql_pool_name]):get() local ppst = conn:setsql("INSERT INTO fw_token (role_id,server_id,custom_id,token,create_time) VALUES (?,?,?,?,NOW())") ppst:set_i32(1,role_id) ppst:set_str(2,config.server_id) ppst:set_i32(3,id) ppst:set_str(4,token) ppst:update() return true,token end return M