【问题标题】:POST signout message to Tableau Server fails using Indy or TWebBrowser使用 Indy 或 TWebBrowser 向 Tableau Server 发布注销消息失败
【发布时间】:2018-06-21 17:03:13
【问题描述】:

在使用 Tableau Server API 测试版 2018.2 时,该文档列出了一个 REST api 调用,用于注销/结束自定义应用程序和 Tableau Server 之间的安全会话。

通过使用用户名和密码执行 POST 请求(登录)来保护会话,该用户名和密码获取用于进一步请求的令牌。

会话结束后,要遵循的正确安全协议是退出/关闭会话。通过创建包含令牌的自定义身份验证标头字符串,这与请求流过程的方式非常相似。

执行注销时有一个显着的区别,即“注销”请求是 POST 请求,而不是 GET 请求。虽然这不应该造成问题,但它似乎是一个问题。

signout POST 请求与任何其他 POST 请求的主要区别在于,signout 请求的数据是 nil/null。基于 API 文档没有提及这一点,而是给出了一个简单的 CURL 示例:

curl "http://MY-SERVER/api/3.0/auth/signout" -X POST -H "X-Tableau-Auth:12ab34cd56ef78ab90cd12ef34ab56cd"

...必须假设执行 POST 请求而不发送数据的行为被认为是正常功能。

我已经使用 TIdHTTP 组件尝试了这个请求,并为 post 调用中的 POST 数据参数提供了一个空的 TStringStream 或一个空的 TStringList:

try
  tss := TStringStream.Create('');
  http.Request.RawHeaders.AddValue('X-Tableau-Auth',FToken);
  http.Post('http://<myserver>/api/3.0/auth/signout',tss);
finally
  tss.Free;
end;

...但收到“HTTP/1.1 401 Unauthorized”异常。

如果我尝试使用 TWebBrowser 界面执行此操作:

var
  flags,headers,postdata,targetframe,url: OleVariant;
begin
  url := 'http://<myserver>/api/3.0/auth/signout';
  headers := 'X-Tableau-Auth: ' + FToken + #13#10;
  targetframe := 1;
  flags := 1;
  postdata := VarArrayCreate([0,1],varByte);
  postdata[0] := 1;
  Navigate2(URL,flags,targetframe,postdata,Headers);
end;

...我第一次意外启动 Internet Exploder,在 url 框中显示注销 url,并显示一个页面显示“导航已取消”。

如果我再次运行代码,我会再次启动不受欢迎的 Internet Exploder,这次会出现以下响应/页面:

<?xml version="1.0" encoding="UTF-8"?>
-<tsResponse xsi:schemaLocation="http://tableau.com/api http://tableau.com/api/ts-api-3.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://tableau.com/api">
-<error code="401002">
<summary>Unauthorized Access</summary>
<detail>Invalid authentication credentials were provided.</detail>
</error>

我更愿意使用 TIdHttp 组件来完成这个小任务,但必须使用 TWebBrowser 来完成视觉任务,所以我也可以使用它。

这里是登出 api 调用的 Tableau Server 文档的链接:

https://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Sign_Out%3FTocPath%3DAPI%2520Reference|_____90

【问题讨论】:

    标签: http delphi post indy tableau-api


    【解决方案1】:

    TIdHTTP 准备发送新的HTTP 请求时,TIdHTTP.Request.RawHeaders 属性将被清除并重新填充要发送的实际标头。由于您将会话令牌存储在 RawHeaders 中,因此它会被清除并且不会发送到服务器,这就是您收到 401 错误的原因。

    您需要改用TIdHTTP.Request.CustomHeaders 属性,该属性在准备请求时添加到RawHeaders

    tss := TStringStream.Create('');
    try
      http.Request.CustomHeaders.AddValue('X-Tableau-Auth',FToken);
      // or:
      // http.Request.CustomHeaders.Values['X-Tableau-Auth'] := FToken;
      http.Post('http://<myserver>/api/3.0/auth/signout', tss);
    finally
      tss.Free;
    end;
    

    仅供参考,如果你想发布空数据,你可以传入 nil 源指针:

    http.Post('http://<myserver>/api/3.0/auth/signout', TStream(nil));
    

    http.Post('http://<myserver>/api/3.0/auth/signout', TStrings(nil));
    

    【讨论】:

    • 谢谢雷米。我做了你所说的,并且有标题来证明它(;-)但它仍然不起作用。我目前正在探索不同的接受、内容类型、字符集等选项,看看是否还有其他事情发生。连接:keep-alive 内容编码:UTF-8 内容类型:text/html; charset=ISO-8859-1 X-Tableau-Auth: NEzHHW7PTX2GDQ3Vz5_K-w|2vhHHjwcg1zJjC4u5Z9AnJGHEcwSMKRK 主机: 接受: application/json 用户代理: Mozilla/3.0 (compatible; Indy Library) 仍然收到 http 1.1/401 未经授权的错误。 ..
    • UTF-8 不是 Content-Encoding 标头的有效值。如果您不发送任何正文数据,则无需发送Content-Type 标头。但这与您的 401 错误无关。您的身份验证令牌无效,或者服务器出于其他原因拒绝身份验证。请联系服务器管理员寻求帮助。
    • 但是...等等...“服务器管理员”联系您寻求帮助。这不是“循环引用”吗? ;-\
    • @DeCoder OP 不是服务器管理员,只是试图与服务器交互的用户。
    • Remy - 明确地说,我是 OP、服务器管理员、程序员、首席厨师和洗瓶器等。
    【解决方案2】:

    好的,想通了。在我的代码中,没有添加带有身份验证信息的标头。此外,将http.Connection 设置为“关闭”。

    这解决了问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-16
      • 2010-12-02
      • 1970-01-01
      相关资源
      最近更新 更多