local core = require("apisix.core") local redis = require("resty.redis") local _M = {} function _M.access(conf, ctx) if not ngx or not ngx.var then core.log.warn("Not in request context, skipping auth check") return end local request_uri = ngx.var.uri core.log.info("REQUEST_DEBUG: uri = "..request_uri) local white_list = { ["/api/v3/login"] = true, ["/admin/v3/login"] = true, ["/admin/v3/refresh"] = true, ["/api/v3/version"] = true, } local user_key = core.request.header(ctx, "authorization") local service_code = core.request.header(ctx, "authorization-type") local req_auth = core.request.header(ctx, "authorization-auth") local refresh = core.request.header(ctx, "refresh") local skip_auth = white_list[request_uri] if skip_auth then core.log.info("WHITE_LIST_DEBUG: hit white list "..request_uri) -- 白名单只标记,不return,不再此处set_header else -- 非白名单完整鉴权逻辑 if not user_key or user_key == "" then return core.response.exit(200, {code = 10003, message = "未登录"}) end if not service_code or service_code == "" then return core.response.exit(200, {code = 10003, message = "未登录"}) end local redis_config = core.config.local_conf().redis or {} local redis_host = redis_config.host or "127.0.0.1" local redis_port = redis_config.port or 6379 local redis_password = redis_config.password or "" local redis_db = redis_config.db or 0 local redis_key = "login:service:" .. service_code .. ":token:" .. user_key local red = redis:new() red:set_timeouts(1000, 1000, 1000) local ok, err = red:connect(redis_host, redis_port) if not ok then red:set_keepalive(10000, 100) return core.response.exit(200, {code = 10003, message = "系统错误,请稍后重试"}) end if redis_password ~= "" then local auth_ok, auth_err = red:auth(redis_password) if not auth_ok then red:set_keepalive(10000, 100) return core.response.exit(200, {code = 10003, message = "系统错误,请稍后重试"}) end end if redis_db > 0 then red:select(redis_db) end local res, err = red:get(redis_key) core.log.error("AUTH_DEBUG host=", redis_host, " port=", redis_port, " password=", redis_password, " db=", redis_db, " key=[", redis_key, "] err=[", tostring(err), "] res=[", tostring(res), "]") red:set_keepalive(10000, 100) if err or res == ngx.null then return core.response.exit(200, {code = 10003, message = "未登录或登录已过期"}) end local json, decode_err = core.json.decode(res) if not json then return core.response.exit(200, {code = 10003, message = "数据解析错误"}) end if service_code == "admin1" then if not req_auth or req_auth == "" then return core.response.exit(200, {code = 10008, message = "没有权限访问该资源"}) end local roles = json.roles or {} local expect_path = roles[req_auth] if not expect_path then return core.response.exit(200, {code = 10008, message = "没有权限访问该资源"}) end local full_expect_uri = "/" .. expect_path local match = false if expect_path:sub(-1) == "*" then local base = expect_path:sub(1, -2) if request_uri:find(base, 1, true) == 1 then match = true end end if request_uri ~= full_expect_uri and not match then return core.response.exit(200, {code = 10008, message = "没有权限访问该资源"}) end end if json.id then ngx.req.set_header("X-User-Id", tostring(json.id)) end if json.name then ngx.req.set_header("X-User-Name", json.name) end if json.store_name then ngx.req.set_header("X-Store-Name", json.store_name) end if json.store_id then ngx.req.set_header("X-Store-Id", tostring(json.store_id)) end if json.sale_province then ngx.req.set_header("X-Sale-Province", tostring(json.province)) end if json.sale_mobile then ngx.req.set_header("X-Sale-Mobile", tostring(json.sale_mobile)) end if json.sale_name then ngx.req.set_header("X-Sale-Name", json.sale_name) end if json.sale_id then ngx.req.set_header("X-Sale-Id", tostring(json.sale_id)) end if json.group_id then ngx.req.set_header("X-Group-Id", tostring(json.group_id)) end if json.group_name then ngx.req.set_header("X-Group-Name", tostring(json.group_name)) end if json.type then ngx.req.set_header("X-User-Type", tostring(json.type)) end end ngx.req.set_header("X-Refresh", refresh or "") ngx.req.set_header("X-Service-Code", service_code or "") core.log.info("FINAL_SET_HEADER: X-Refresh=["..(refresh or "").."]") return end return _M