PAYATHON 2026

Delphi 10.2.3 中如何为 THTTPRIO 设置 Bearer token?

数据小许

可以在 THTTPRIO.HTTPWebNode.OnBeforePost 事件中设置 Authorization HTTP 请求头。Delphi Tokyo 10.2.3 在 Windows 上默认使用 WinINet 传输,可以通过 Winapi.WinInet.HttpAddRequestHeaders 添加请求头。

目标请求头格式为:

Authorization: Bearer <token>

将 <token> 替换为服务认可的实际 token,不要包含尖括号。

为什么使用 OnBeforePost?

Bearer token 是 HTTP 层的认证信息,应放在 HTTP 请求头中。OnBeforePost 在请求内容和请求头准备好之后、实际发送之前触发,可以在此时补充认证头。Embarcadero 事件说明

Delphi 10.2.3 的 WinINet 示例

以下代码假设窗体中已有 HTTPRIO1: THTTPRIO。将这些单元加入现有的 uses:

uses
  System.SysUtils,
  Winapi.Windows,
  Winapi.WinInet,
  Soap.SOAPHTTPTrans;

在现有窗体类的 private 部分加入 token 字段和事件处理方法:

private
  FBearerToken: string;
  procedure BeforeSOAPPost(const HTTPReqResp: THTTPReqResp;
    Data: Pointer);

实现事件处理方法:

procedure TForm1.BeforeSOAPPost(const HTTPReqResp: THTTPReqResp;
  Data: Pointer);
var
  AuthHeader: string;
begin
  if FBearerToken = '' then
    raise Exception.Create('Bearer token 不能为空');

  AuthHeader := 'Authorization: Bearer ' + FBearerToken + #13#10;

  if not Winapi.WinInet.HttpAddRequestHeaders(
    Data,
    PChar(AuthHeader),
    Length(AuthHeader),
    HTTP_ADDREQ_FLAG_ADD or HTTP_ADDREQ_FLAG_REPLACE
  ) then
    RaiseLastOSError;
end;

在第一次调用 SOAP 方法之前,设置实际 token 并绑定事件:

FBearerToken := 'YOUR_ACCESS_TOKEN'; // 替换为实际 token
HTTPRIO1.HTTPWebNode.OnBeforePost := BeforeSOAPPost;

之后按原来的方式调用 SOAP 接口。token 更新时,修改 FBearerToken 即可,后续请求会读取新值。示例中的 TForm1 应替换为项目实际的窗体类名。

HTTP_ADDREQ_FLAG_ADD or HTTP_ADDREQ_FLAG_REPLACE 在请求头不存在时添加,存在时替换。Length(AuthHeader) 传入的是字符数。调用失败时应立即读取系统错误,示例使用 RaiseLastOSError 抛出异常。Microsoft API 说明

如果项目启用了 USE_INDY

上面的代码要求 Data 是 WinINet 请求句柄。如果项目重新编译了 Soap.SOAPHTTPTrans 并启用了 USE_INDY,应根据该实现将 Data 作为 TIdHTTP 对象使用,不能继续传给 WinINet API。

确认使用该 Indy 实现后,加入 IdHTTP 单元,并将事件处理方法改为:

procedure TForm1.BeforeSOAPPost(const HTTPReqResp: THTTPReqResp;
  Data: Pointer);
var
  HTTP: TIdHTTP;
begin
  if FBearerToken = '' then
    raise Exception.Create('Bearer token 不能为空');

  HTTP := TIdHTTP(Data);
  HTTP.Request.BasicAuthentication := False;
  HTTP.Request.CustomHeaders.Values['Authorization'] :=
    'Bearer ' + FBearerToken;
end;

代码中显式关闭了 Basic authentication,避免自动生成的 Basic 认证信息干扰自定义认证头。Indy 的认证处理和请求对象实现可参阅其项目源码。输入信息没有说明是否启用了 USE_INDY,请根据项目实际使用的传输实现选择写法。

设置后仍无法通过认证时

先确认事件确实执行,再检查服务端收到的请求是否包含唯一且正确的 Authorization: Bearer ...。不要继续使用旧的 Basic 认证配置,也不要给 token 额外添加引号或换行。

如果请求头正确但服务仍拒绝访问,请按服务的认证规则核对 token 是否过期、权限是否满足要求,以及是否适用于当前服务。添加请求头只负责携带 token,不负责获取或刷新 token;这部分流程需要查阅服务提供方的接口说明。

使用 HTTPS 发送 token,排查问题时应在日志中遮蔽 token 的完整值。

备注:内容仅供参考。