如何在HAProxy中仅当返回401状态码时拦截用户与DeviceID
HAProxy 仅在返回401时拦截指定DeviceID用户的实现方案
核心思路
通过HAProxy的stick table存储需要拦截的DeviceID,仅当后端返回401状态码时,将请求中的DeviceID标记为拦截对象,后续同DeviceID的请求直接被拦截。
具体配置示例
1. 定义Stick Table
在HAProxy配置中定义用于存储拦截标记的stick table:
# 定义字符串类型的stick table,存储DeviceID,最多容纳10万条记录,1小时后自动过期 stick-table type string size 100k expire 1h store gpc0
2. Frontend 处理逻辑
在前端监听中提取URL参数里的DeviceID,并检查是否在拦截列表中:
frontend main bind *:80 # 从URL参数中提取DeviceID,存入事务变量txn.device_id http-request set-var(txn.device_id) url_param(DeviceID) # 若DeviceID存在且已被标记为拦截,直接返回403拒绝请求 http-request deny deny_status 403 if { var(txn.device_id) -m found } { table_gpc0(backend/main) gt 0 } # 将请求转发至后端服务 default_backend app_server
3. Backend 拦截标记逻辑
在后端配置中,当服务返回401时,将当前请求的DeviceID加入拦截列表:
backend app_server server app1 192.168.1.10:80 check # 仅当后端返回401状态码且DeviceID存在时,标记该DeviceID为拦截对象 http-response set-table gpc0 1 if { status eq 401 } { var(txn.device_id) -m found }
关键配置说明
url_param(DeviceID):从GET请求的URL参数中提取DeviceID;若DeviceID在POST请求体中,需替换为req.body_param(DeviceID),同时注意调整HAProxy的缓冲区大小(tune.bufsize)以支持大请求体解析。table_gpc0(backend/main):检查指定stick table中对应DeviceID的gpc0值(此处用作拦截标记,值为1表示需要拦截)。expire 1h:可根据业务需求调整拦截时长,比如设置为expire 24h表示拦截24小时。
扩展场景:基于IP+DeviceID拦截
若需要同时关联用户IP和DeviceID进行拦截,可修改stick table类型为复合类型,并调整变量:
# 定义IP+字符串类型的stick table,存储IP与DeviceID的组合 stick-table type ip+string size 100k expire 1h store gpc0 # Frontend中组合IP与DeviceID http-request set-var(txn.ip_device) concat(src,var(txn.device_id)) http-request deny deny_status 403 if { var(txn.ip_device) -m found } { table_gpc0(backend/main) gt 0 } # Backend中标记组合值 http-response set-table gpc0 1 if { status eq 401 } { var(txn.ip_device) -m found }
内容的提问来源于stack exchange,提问作者ethan eric
相关产品推荐
相关产品推荐

