Created
          October 6, 2024 04:15 
        
      - 
      
 - 
        
Save lukluk/5b83da528cbb99afffaf6f1b56666b1e to your computer and use it in GitHub Desktop.  
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | local redis = require "resty.redis" | |
| local ngx_log = ngx.log | |
| local kickout = "kickout." | |
| local kg = "kong." | |
| local logout = "logout" | |
| local setmetatable = setmetatable | |
| local expired_duration = 604800 | |
| local _M = {} | |
| local function send_to_stdlog(message) | |
| return ngx_log(ngx.NOTICE, message) -- this only works with LuaJIT | |
| end | |
| local function set_device_id(red, sub, device_id) | |
| local ok, err = red:exists(kg .. sub) | |
| if err then | |
| ngx.log(ngx.ERR, "Failed to check exists Redis: ", err) | |
| end | |
| if ok == 1 then | |
| return false | |
| end | |
| red:set(kg ..sub, device_id, "EX", expired_duration) | |
| return true | |
| end | |
| function _M:logout_flag(conf, token) | |
| local red = redis:new() | |
| local ok, err = red:connect(conf.redis_host, conf.redis_port) | |
| if not ok then | |
| ngx.log(ngx.ERR, "Failed to connect to Redis: ", err) | |
| return err | |
| end | |
| red:set(kg .. logout .. token, "1", "EX", expired_duration) | |
| end | |
| function _M:is_token_active(conf, token) | |
| local red = redis:new() | |
| local ok, err = red:connect(conf.redis_host, conf.redis_port) | |
| if not ok then | |
| ngx.log(ngx.ERR, "Failed to connect to Redis: ", err) | |
| return err | |
| end | |
| local ok, err = red:exists(kg .. logout .. token) | |
| if err then | |
| ngx.log(ngx.ERR, "Failed to check exists Redis: ", err) | |
| end | |
| if ok == 1 then | |
| return false | |
| end | |
| return true | |
| end | |
| local function get_old_device_id(red, sub, device_id) | |
| local value, err = red:get(kg .. sub) | |
| return value | |
| end | |
| local function close_redis(red) | |
| local ok, err = red:set_keepalive(10000, 100) | |
| if not ok then | |
| ngx.log(ngx.ERR, "Failed to set Redis connection keepalive: ", err) | |
| end | |
| end | |
| function _M:device_session(conf, sub, device_id) | |
| if not conf.is_ban_multi_devices then | |
| return nil | |
| end | |
| -- Create a Redis connection | |
| local red = redis:new() | |
| local ok, err = red:connect(conf.redis_host, conf.redis_port) | |
| if not ok then | |
| ngx.log(ngx.ERR, "Failed to connect to Redis: ", err) | |
| return err | |
| end | |
| local kicked_out_device_ids, err = red:get(kg .. kickout .. sub) | |
| if err then | |
| close_redis(red) | |
| ngx.log(ngx.ERR, "Failed to set kickout to Redis: ", err) | |
| return err | |
| end | |
| if kicked_out_device_ids == ngx.null then | |
| kicked_out_device_ids = "" | |
| end | |
| if not string.find(kicked_out_device_ids, device_id, 1, true) then | |
| local ok = set_device_id(red, sub, device_id) | |
| if not ok then | |
| local old_device_id = get_old_device_id(red, sub, device_id) | |
| if old_device_id ~= device_id then | |
| red:set(kg .. sub, device_id, "EX", expired_duration) | |
| red:set(kg .. kickout .. sub, kicked_out_device_ids .. "," .. old_device_id, "EX", 300) | |
| close_redis(red) | |
| return nil, 200 | |
| end | |
| end | |
| else | |
| close_redis(red) | |
| return nil, 409 | |
| end | |
| close_redis(red) | |
| return nil | |
| end | |
| return _M | 
  
    Sign up for free
    to join this conversation on GitHub.
    Already have an account?
    Sign in to comment