当前位置: 首页 > news >正文

Delphi WebService 使用 HTTP Header 管理 Session

背景知识

使用 Delphi 的 WebBroker 框架可以开发标准的 Web Server 程序。

使用 Delphi 的 SOAP 框架,可以开发支持 SOAP 标准的 WebService 服务端程序。此框架建立的 WebBroker 框架之上。

使用 Delphi 可以开发客户端程序,去调用 WebService 服务器提供的 SOAP 函数。同时也可以去调用 WebBroker 开发的 Web Server 提供的 RESTfull 的 URL 接口。

问题

WebBroker 的架构下,客户端和服务器端没有长连接,是无状态的。也就是服务器端并不能记住客户端的上一次访问。因此,需要一个 Session 机制。

因为是 Web 访问,可以采用 HTTP Cookie 来让客户端和服务器端之间维护一个 Session。这个方式的好处是客户端基本上不需要写代码。

但是,

如果应用程序的代码框架比较复杂,比如同一个客户端,可能需要访问多个不同的 WebService 服务器端,甚至同时还要访问多个 WebBroker 的 WebServer 服务器端。此时,Cookie 因为不能跨域,从一个 WebService 服务器端程序获得的 HTTP Cookie 无法让另外一个服务器端程序读到。

如果要在多个 WebService 服务器端程序之间保持同一个 Session,则需要考虑使用另外两种方式:

1. 在 URL 里面,加上 Session 有关的参数;

2. 在 HTTP Header 里面加上 Session 有关的参数;

使用 HTTP Header 来维护 Session 的代码实现

客户端

客户端如果使用 HTTRIO 去调用服务器端的函数,设计期选中 HTTPRIO1,属性面板里面,事件标签页,HTTPWebNode 下拉开,找到OnBeforePost事件,双击产生事件方法代码:

uses Soap.SOAPHTTPTrans; procedure TForm2.HTTPRIO1HTTPWebNode1BeforePost(const HTTPReqResp: THTTPReqResp; Client: THTTPClient); begin Client.CustomHeaders['ABC'] := 'abcdexyz'; end;

则每次使用这个 httpRIO1 来调用服务器端方法时,都会为 HTTP 加上一个名字为 abc 的 Header;

SoapConnection 的问题是,它内部的 RIO 不是一直存在的。为它设置了 URL 以后,需要设置它的 Connected 属性为 True,这个 RIO 才会被创建出来。

因此,代码可能需要显示地执行 SoapConnection1.Connected := True; 然后再判断是否有 RIO,如果有,则执行以下代码绑定事件:

SoapConnection1.RIO.HTTPWebNode.OnBeforePost := TForm2.HTTPRIO1HTTPWebNode1BeforePost;

这样绑定后,SoapConnection 和 HTTPRIO 应该就能共享同一个 HTTP Header 的代码了。

以下代码测试通过:

procedure TForm2.Button2Click(Sender: TObject); begin SoapConnection1.Connected := True; if Assigned(SoapConnection1.RIO) then begin SoapConnection1.RIO.HTTPWebNode.OnBeforePost := HTTPRIO1HTTPWebNode1BeforePost; end; ClientDataSet1.Close; ClientDataSet1.Open; end;

服务器端

服务器端在接口方法的实现里面,直接读取 HTTP Header: 的代码:

uses SOAP.WebBrokerSOAP, web.HttpApp; { TtestHeader } function TtestHeader.testHeader: string; begin Result := GetSOAPWebModule.Request.GetFieldByName('abc'); end;

服务器端的 Soap Data Module:对应客户端的 SoapConnection 当客户端的 ClientDataSet.Open 的时候,服务器端的 DataSetProvider.BeforeGetRecords 事件里面写代码,读 Header 是否正确,代码如下:

uses SOAP.WebBrokerSOAP, web.HttpApp; {$R *.DFM} procedure TMyDataCreateInstance(out obj: TObject); begin obj := TMyData.Create(nil); end; function TMyData.CheckHeader: Boolean; begin Result := 'abcdexyz' = GetSOAPWebModule.Request.GetFieldByName('abc'); end; procedure TMyData.DataSetProvider1BeforeGetRecords(Sender: TObject; var OwnerData: OLEVariant); begin if not CheckHeader then raise Exception.Create('身份验证没通过'); end;

总之服务器端不管是接口方法的实现部分,还是 SoapDataModule 里面,都是调用:GetSOAPWebModule.Request.GetFieldByName('abc');去读取 Header 来获得客户端提交的 Session ID 或者说: Token

客户端使用 IdHTTP

procedure TForm2.Button3Click(Sender: TObject); var S: string; begin IdHTTP1.Request.CustomHeaders.Values['abc'] := 'abcde'; S := IdHTTP1.Get('http://localhost:8080/MyHeader'); Log(S); end;

上述代码,使用 TIdHTTP 作为 HTTP 客户端去请求一个 WebBroker 服务器端的 MyHeader 路径。请求之前添加了一个自定义的 CustomHeader

然后,WebBroker 服务器端对应的代码,通过以下方法读客户端传过来的 HTTP Header:

procedure TWebModule1.WebModule1MyHeaderAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); var S: string; begin S := Request.GetFieldByName('abc'); Response.Content := S; end;
http://www.jsqmd.com/news/1395229/

相关文章:

  • 08.13每日总结
  • IIS8.5伪静态配置实战:人才招聘系统迁移指南
  • 36、傅里叶级数的复指数形式
  • 2026手游搬砖多开24小时托管用什么云手机?
  • 2026年8月重庆市渝北区广电500M单宽带小白怎么选宽带 - 找卡家园
  • 2026年8月石家庄市新华区电信600M宽带怎么选一篇说透 - 找卡家园
  • IDEA搭建Rust开发环境:从工具链配置到高效编码实战
  • IntelliJ IDEA中Maven依赖解析失败:三种核心解决方案与实战排查指南
  • 2027亚洲AI算力液冷技术展官方一站式解决企业发展痛点
  • RabbitMQ exchange交换机机制
  • AI工具依赖下的能力退化:如何避免成为技术的附庸
  • Book118付费文档免费下载全攻略:三步用开源下载器把预览页变成PDF
  • 2026年8月邢台市广宗县联通1000M宽带怎么选 - 找卡家园
  • 2026年8月石家庄市新华区电信300M宽带怎么选 - 找卡家园
  • CFD Vision 2030的2026年进展:航空航天计算流体力学的技术演进与未来方向
  • 2026年8月无锡市锡山区电信300M单宽带避坑指南一篇说透 - 找卡家园
  • Windows批处理脚本实战:用MD/MKDIR命令批量自动化创建文件夹
  • 数学建模竞赛实战指南:从模型构建到论文写作的完整路径
  • FGO材料规划工具Chaldea:攒石、刷本、模拟战斗,一次理顺
  • G-Helper启动失败的快速修复指南:从闪退到正常运行的完整排查方案
  • 清华蓝莲花CTF实战教程:从零搭建环境到Web安全、逆向工程、密码学入门
  • 【Kubernetes从入门到精通】第43篇:K8s网络模型——“每个Pod一个独立IP“背后的大智慧
  • Mac 版 Navicat 试用期到期怎么办?一篇讲透无限试用重置原理、三种方案与避坑清单
  • 单片机毕设选题推荐:基于 STM32 的健康体征检测与声光告警终端开发 基于 STM32 的便携式人体心率血氧监测仪设计(013203)
  • Windows 11 卡顿的元凶不在你装的软件里:用 Win11Debloat 清理预装应用与遥测,3 步告别系统臃肿
  • 3 分钟免费把 GIMP 变成 Photoshop:PhotoGIMP 界面补丁完整上手指南
  • 前端构建安全:防范资源中毒与依赖风险实战指南
  • 2026年8月无锡市锡山区电信200M单宽带避坑全攻略 - 找卡家园
  • MathType与Word集成故障排查:COM插件加载失败与快捷键冲突修复指南
  • 北京离婚财产分割律师哪家专业?看这篇就够了 - 品牌排行榜