控制台内嵌及分享(新版)

重要

本文中含有需要您注意的重要提示信息,忽略该信息可能对您的业务造成影响,请务必仔细阅读。

如果您需要将日志服务的查询分析结果、仪表盘等页面,分享给其他人或者嵌入到第三方系统,可以通过本文生成免密且免登录的链接进行分享。本文将介绍详细操作步骤。

背景信息

Ticket是指一个短期有效的令牌(Token),用于拼接免密且免登录链接,获取链接的用户无需登录阿里云账户,就可以访问指定的查询分析页面或仪表盘页面。

操作流程如下:

  1. 为RAM用户授权。

  2. 准备分享链接。

  3. 调用CreateTicket接口获取Ticket

  4. Ticket拼接到分享链接中,生成免密且免登录链接。

警告

生成的链接会继承CreateTicket接口调用者在日志服务中已有的权限,为避免使用主账号调用接口而造成的数据安全风险,在该场景中强烈建议使用RAM用户来调用CreateTicket接口,并为该RAM用户设置最小化的权限范围,具体参见下面的步骤一:为RAM用户授权

生成免密且免登录的链接

步骤一:为RAM用户授权

如果使用阿里云主账号,可跳过这步,直接前往步骤二。

  1. 创建RAM用户

  2. 为RAM用户授予指定资源(Project、Logstore)的权限和调用CreateTicket接口的权限。

    1. 授予指定资源权限的步骤,请参见RAM自定义授权示例

    2. 授予调用CreateTicket接口,具体操作步骤请参见为RAM用户授权创建自定义权限策略

      {
          "Version": "1",
          "Statement": [
              {
                  "Effect": "Allow",
                  "Action": "log:CreateTicket",
                  "Resource": "acs:log:*:*:ticket/*"
              }
          ]
      }

步骤二:准备链接

  • 查询分析页面:

    https://sls.console.aliyun.com/lognext/project/<Project名称>/logsearch/<日志库名称>?slsRegion=<Project所在地域>&hideTopbar=true&hideSidebar=true&ignoreTabLocalStorage=true

    Project名称参见管理Project,日志库名称参见管理Logstore,Project所在地域参见服务接入点地域ID。

  • 查询页面:

    https://sls.console.aliyun.com/lognext/project/<Project名称>/logsearch/<日志库名称>?slsRegion=<Project所在地域>&isShare=true&hideTopbar=true&hideSidebar=true&ignoreTabLocalStorage=true
  • 仪表盘页面:

    重要

    仪表盘ID为网页链接上的ID,并非仪表盘的展示名称。仪表盘免密分享也可以在控制台操作,具体步骤请参见仪表盘免密分享

    https://sls.console.aliyun.com/lognext/project/<Project名称>/dashboard/<仪表盘ID>?slsRegion=<Project所在地域>&isShare=true&hideTopbar=true&hideSidebar=true&ignoreTabLocalStorage=true

步骤三:获取票据Ticket

重要
  • 调用CreateTicket获取票据Ticket,服务地址只能是华东2(上海)新加坡,但获取的Ticket可以在各个地域使用。

  • 生成的票据Ticket只能使用一次,有效期默认为一天,最长为30天。如果需要动态生成Ticket,请参见下面的如何动态生成Ticket?

image

步骤四:拼接免密且免登录链接

  1. 将步骤二的链接与票据Ticket拼接,生成免密且免登录访问链接。

    https://sls.console.aliyun.com/lognext/project/<Project名称>/dashboard/<仪表盘ID>?slsRegion=<Project所在地域>&sls_ticket=eyJ***************.eyJ******************.KUT****************&isShare=true&hideTopbar=true&hideSidebar=true&ignoreTabLocalStorage=true
  2. 链接测试。您可以将生成的免登录链接输入浏览器的地址栏进行测试。若可正常打开日志服务控制台分享页面,则说明已成功生成免登录链接。

    警告
    • 此处测试即为首次在浏览器中打开免登录链接,测试完成后,票据Ticket会失效。您需要重新调用CreateTicket获取新的票据Ticket。

    • 建议将链接复制到文件中,然后传输文件。如果直接在第三方软件中发送链接,可能因为被第三方软件读取而失效。

常见问题

如何延长内嵌访问时间?

延长内嵌访问时间请参见控制台内嵌及分享(新版)延长访问时间

如何动态生成Ticket?

如果在第三方系统中嵌入控制台页面,则需要在应用程序中动态调用CreateTicket接口,以定期获取Ticket。如果使用RAM用户的长期访问密钥调用接口,操作步骤简单,但安全风险较高,建议使用具有临时身份凭证(STS Token)的RAM角色调用接口,可以降低安全风险。

  1. 创建RAM用户创建可信实体为阿里云账号的RAM角色

  2. 为RAM用户授予STS的管理权限(AliyunSTSAssumeRoleAccess),为RAM角色授予调用CreateTicket接口的权限日志服务的相关权限,授权操作请参见为RAM角色授权RAM自定义授权示例

  3. 使用RAM角色调用CreateTicket接口。

    1. 使用RAM用户调用AssumeRole接口,获取SecurityToken、AccessKeySecret和AccessKeyId。

    2. RAM用户使用这三个参数扮演RAM角色,从而调用CreateTicket接口获取Ticket。

      SDK示例

      Java

      1. 添加Maven依赖。

        在Java项目的根目录下,打开pom.xml文件,添加以下代码:

            <dependency>
              <groupId>com.aliyun</groupId>
              <artifactId>sls20201230</artifactId>
              <version>5.2.1</version>
            </dependency>
            <dependency>
              <groupId>com.aliyun</groupId>
              <artifactId>tea-openapi</artifactId>
              <version>0.3.2</version>
            </dependency>
            <dependency>
              <groupId>com.aliyun</groupId>
              <artifactId>tea-console</artifactId>
              <version>0.0.1</version>
            </dependency>
            <dependency>
              <groupId>com.aliyun</groupId>
              <artifactId>tea-util</artifactId>
              <version>0.2.21</version>
            </dependency>
      2. 创建生成票据代码。

        import com.aliyun.tea.*;
        
        public class Sample {
        
            /**
             * 使用AK&SK初始化账号Client
             * @return Client
             * @throws Exception
             */
            public static com.aliyun.sls20201230.Client createClient() throws Exception {
                // 工程代码泄露可能会导致 AccessKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考。
                // 建议使用更安全的 STS 方式。
                com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
                        // 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID。
                        .setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"))
                        // 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
                        .setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
                // Endpoint 请参考 https://api.aliyun.com/product/Sls
                config.endpoint = "cn-shanghai.log.aliyuncs.com";
                return new com.aliyun.sls20201230.Client(config);
            }
        
            public static void main(String[] args_) throws Exception {
                java.util.List<String> args = java.util.Arrays.asList(args_);
                com.aliyun.sls20201230.Client client = Sample.createClient();
                com.aliyun.sls20201230.models.CreateTicketRequest createTicketRequest = new com.aliyun.sls20201230.models.CreateTicketRequest();
                com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
                java.util.Map<String, String> headers = new java.util.HashMap<>();
                try {
                    com.aliyun.sls20201230.models.CreateTicketResponse resp = client.createTicketWithOptions(createTicketRequest, headers, runtime);
                    com.aliyun.teaconsole.Client.log(com.aliyun.teautil.Common.toJSONString(resp));
                } catch (TeaException error) {
                    // 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
                    // 错误 message
                    System.out.println(error.getMessage());
                    // 诊断地址
                    System.out.println(error.getData().get("Recommend"));
                    com.aliyun.teautil.Common.assertAsString(error.message);
                } catch (Exception _error) {
                    TeaException error = new TeaException(_error.getMessage(), _error);
                    // 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
                    // 错误 message
                    System.out.println(error.getMessage());
                    // 诊断地址
                    System.out.println(error.getData().get("Recommend"));
                    com.aliyun.teautil.Common.assertAsString(error.message);
                }
            }
        }

      Python

      # -*- coding: utf-8 -*-
      # This file is auto-generated, don't edit it. Thanks.
      import os
      import sys
      
      from typing import List
      
      from alibabacloud_sls20201230.client import Client as Sls20201230Client
      from alibabacloud_tea_openapi import models as open_api_models
      from alibabacloud_sls20201230 import models as sls_20201230_models
      from alibabacloud_tea_util import models as util_models
      from alibabacloud_tea_util.client import Client as UtilClient
      
      
      class Sample:
          def __init__(self):
              pass
      
          @staticmethod
          def create_client() -> Sls20201230Client:
              """
              使用AK&SK初始化账号Client
              @return: Client
              @throws Exception
              """
              # 工程代码泄露可能会导致 AccessKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考。
              # 建议使用更安全的 STS 方式,更多鉴权访问方式请参见:https://help.aliyun.com/document_detail/378659.html。
              config = open_api_models.Config(
                  # 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID。,
                  access_key_id=os.environ['ALIBABA_CLOUD_ACCESS_KEY_ID'],
                  # 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。,
                  access_key_secret=os.environ['ALIBABA_CLOUD_ACCESS_KEY_SECRET'],
                  # 必填,请确保代码运行环境设置了安全令牌SecurityToken
                  security_token=os.environ['ALIBABA_CLOUD_Token']
              )
              # Endpoint 请参考 https://api.aliyun.com/product/Sls
              config.endpoint = f'cn-shanghai.log.aliyuncs.com'
              return Sls20201230Client(config)
      
          @staticmethod
          def main(
              args: List[str],
          ) -> None:
              client = Sample.create_client()
              create_ticket_request = sls_20201230_models.CreateTicketRequest(
                  expiration_time=300
              )
              runtime = util_models.RuntimeOptions()
              headers = {}
              try:
                  # 复制代码运行请自行打印 API 的返回值
                  client.create_ticket_with_options(create_ticket_request, headers, runtime)
              except Exception as error:
                  # 此处仅做打印展示,请谨慎对待异常处理,在工程项目��切勿直接忽略异常。
                  # 错误 message
                  print(error.message)
                  # 诊断地址
                  print(error.data.get("Recommend"))
                  UtilClient.assert_as_string(error.message)
      
          @staticmethod
          async def main_async(
              args: List[str],
          ) -> None:
              client = Sample.create_client()
              create_ticket_request = sls_20201230_models.CreateTicketRequest(
                  expiration_time=300
              )
              runtime = util_models.RuntimeOptions()
              headers = {}
              try:
                  # 复制代码运行请自行打印 API 的返回值
                  await client.create_ticket_with_options_async(create_ticket_request, headers, runtime)
              except Exception as error:
                  # 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
                  # 错误 message
                  print(error.message)
                  # 诊断地址
                  print(error.data.get("Recommend"))
                  UtilClient.assert_as_string(error.message)
      
      
      if __name__ == '__main__':
          Sample.main(sys.argv[1:])
  4. 根据返回的Ticket拼接出不同权限范围的免密链接。

SDK请求CreateTicket报错:InvalidMethod

服务地址Endpoint只能是华东2(上海)或新加坡,但获取的Ticket可以在各个地域使用。

Ticket限制

  • Ticket默认有效时长为24小时,最长为30天。

  • 每个Ticket只能被同一个浏览器或主机访问。例如在浏览器A中打开的免密链接可以持续访问,但是在浏览器B中无法打开链接。

  • 生成Ticket的总数没有限制,CreateTicket QPS限制为每用户10次/s。

第三方cookie限制

使用控制台内嵌及分享(新版)不依赖第三方cookie。

内嵌页面加载速度

使用控制台内嵌及分享(新版)相比老版,有更高的加载速度。

需要开多个内嵌页面,每个内嵌页面权限相同

  1. 可以生成一个Ticket,然后在同一个浏览器中刷新页面。当Ticket过期时,重新生成新的Ticket,然后替换所有Tab页的Ticket。

  2. 不同浏览器或电脑会被视为不同的用户,因为一个ticket只能使用一次,所以会报错:

    {"code":"TicketUnavailable","message":"There are no more tickets available.","requestId":"xxxxxx","success":false}

需要开多个内嵌页面,每个内嵌页面权限不同

  1. 可以生成多个Ticket,每个Ticket关联不同的权限,但只有最后一个Ticket对应的内嵌页面可以刷新,原因是只能记录一个cookie作为当前使用者的凭证,对应最后生成的Ticket,每次刷新会根据该cookie作为当前的使用者。

  2. 在不刷新页面的情况下,不需要用到cookie,仍然可以切换标签页并操作不同内嵌页面的内容,对应的权限也不同。

  3. 此时刷新非最后一个ticket对应的内嵌页面,会报错:

    {"code":"TicketUnavailable","message":"There are no more tickets available.","requestId":"xxxxxx","success":false}