代码之家  ›  专栏  ›  技术社区  ›  DeCoder

使用Indy或Twebbrowser向Tableau服务器发送注销后消息失败

  •  0
  • DeCoder  · 技术社区  · 8 年前

    在使用beta版本2018.2的TabLeAuver服务器API时,文档列出了一个REST API调用,它在自定义应用程序和TabLoue服务器之间签出/结束安全会话。

    通过使用请求获得用于进一步请求的令牌的用户名和密码来执行POST请求(Sigin)来保证会话。

    会话完成后,要遵循的正确安全协议是注销/关闭会话。通过创建包含令牌的自定义身份验证头字符串,这与请求流处理的方式相同。

    执行注销时有一个显著的区别,即“注销”请求是post请求,而不是get请求。虽然这不应该构成问题,但似乎是一个问题。

    signout post请求和任何其他post请求的主要区别在于,signout请求的数据为nil/null。基于API文档没有提及这一事实,而是给出了一个简单的卷曲示例:

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

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

    我尝试使用TIDHTTP组件,并为后调用中的POST数据参数提供空TSTRIGSTROW或空TSTRIGLIST:

    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未授权”异常。

    如果我尝试使用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爆炸器,这次是用下面的响应/页面:

    <?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调用的TabLeAO服务器文档的链接:

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

    2 回复  |  直到 8 年前
        1
  •  0
  •   Remy Lebeau    8 年前

    什么时候? TIdHTTP 正在准备新的http请求以发送 TIdHTTP.Request.RawHeaders 属性被清除并重新填充要发送的实际报头。因为您将会话令牌存储在 RawHeaders ,它将被清除而不发送到服务器,这就是为什么 401 错误。

    你需要使用 TIdHTTP.Request.CustomHeaders 属性,它被添加到 拉皮条者 准备请求时:

    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));
    
        2
  •  0
  •   DeCoder    8 年前

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

    这解决了问题。

    推荐文章