DataWorks Embed API - 手把手教您在自建的 Web 嵌入 DataWorks 数据血缘图

本文涉及的产品
实时数仓Hologres,5000CU*H 100GB 3个月
智能开放搜索 OpenSearch行业算法版,1GB 20LCU 1个月
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: DataWorks 提供丰富的数据可视化界面,让用户能轻松地透过界面操作大数据业务,但仍有集成至自建 Web 界面的需求,减少切换页面的频率。下文就以透过阿里云令牌服务结合自建 Web 界面代理登录阿里云,做到嵌入DataWorks数据地图的血缘图。

前言

DataWorks 提供丰富的数据可视化界面,让用户能轻松地透过界面操作大数据业务,但仍有集成至自建 Web 界面的需求,减少切换页面的频率。DataWorks 新推出的 Embed API 透过阿里云令牌服务结合自建 Web 界面代理登录阿里云,做到嵌入DataWorks数据地图的血缘图。


Embed API https://dataworks.data.aliyun.com/cn-shanghai/open/playground/case?id=dataLineageGraph


先看效果图

image.png



登录态处理


登录态的处理有五个方面要处理

  • RAM 帐号
  • 代理 Role
  • 获取临时 AK
  • 获取登录 Token
  • 嵌入页面


其顺序图如下:



RAM 帐号

打开 RAM 访问控制,建立一个 RAM 帐号,并赋予 AliyunSTSAssumeRoleAccess 权限 (使此 RAM 帐号有代理 Role 的权限),以及取得 RAM 帐号的 AK,我们将在自建 Web 里使用这个 RAM 帐号登录获取临时 AK。


若使用 Open API 来新建可参考以下页面:


安全提示: 建议在自建 Web 里,其自运维的用户帐号一对一对应到一个阿里云的 RAM 帐号或 Role,例如自建的 LDAP 系统,每新建一个帐号就自动绑定一个阿里云 RAM 帐号或 Role,并且是一对一的关系不使用共享一个帐号或 Role 的方式


代理 Role

取得 RAM 帐号的 AK 后,使用这个 RAM 来代理一个 Role 并取得临时 AK,打开角色页面,建立一个角色,并取得这个角色的 ARN 码。


若使用 Open API 来新建可参考以下页面:


获取临时 AK

取得角色 ARN 码后,我们已俱备以下信息:

  • RAM 帐号 AK (AccessKeyId, AccessKeySecret)
  • Role ARN
  • 要登录的 DataWorks 的地域 (如上海为 cn-shanghai)


使用 STS 获取临时 AK 的 Open API 接口,接口描述查看


透过此接口我们可取到以下信息:

  • 临时 AK (AccessKeyId, AccessKeySecret)
  • securityToken (安全令牌)


获取登录 Token


取得临时 AK 与安全令牌后,再透过阿里云登录服务 ( signin.aliyun.com/federation ),取得 SigninToken (登录令牌),如以下代码示例。

// get aliyun signing token
const signingUrl = 'https://signin.aliyun.com/federation';
const params = new URLSearchParams();
params.append('Action', 'GetSigninToken');
params.append('AccessKeyId', accessKeyId); // 临时 accessKeyId
params.append('AccessKeySecret', accessKeySecret); // 临时 accessKeySecret
params.append('SecurityToken', securityToken); // 安全令牌
params.append('TicketType', 'mini');
const signingResult = await fetch(signingUrl, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded',
  },
  body: params,
});
const result = await signingResult?.json?.();
console.log(result?.SigninToken);


嵌入页面

取得登录令牌后,组织以下路径,透过 iframe 嵌入即可使用 DataWorks 血缘图。


https://signin.aliyun.com/federation?Action=Login&LoginUrl=${encodedLoginUrl}&Destination=${encodedUrl}&SigninToken=${encodedSinginToken} 


参数说明:

  • encodedLoginUrl: 为登录态失效后的转登页面,通常为 https://signin.aliyun.com
  • encodedUrl: 为最终使用 DataWorks 的界面链接,此处需要 DataWorks 提供可嵌入使用的功能链接。
  • encodedSinginToken: 登录令牌


参考代码

代码范例 (以Node.js为例)


  • index.js
const express = require('express');
const path = require('path');
const LoginAliyun = require('./loginAliyun');
const fetch = require('node-fetch');
const fs = require('fs');
const http = require('http');
const https = require('https');
const privateKey = fs.readFileSync('./sslcert/example.com.key', 'utf8');
const certificate = fs.readFileSync('./sslcert/example.com.crt', 'utf8');

const credentials = { key: privateKey, cert: certificate };

const app = express();

// Have Node serve the files for our built React app
app.use(express.static(path.resolve(__dirname, './client/dist')));

app.get("/getSigninToken", async (req, res) => {

  const regionId = 'cn-shanghai';
  const ramAccessKeyId = 'your ram access key id';
  const ramAccessKeySecret = 'your ram access key secret';
  const roleArn = 'role arn';

  const loginResult = await LoginAliyun.main(ramAccessKeyId, ramAccessKeySecret, regionId, roleArn);
  const credentials = loginResult?.body?.credentials;

  if (!credentials) {
    res.json({ message: 'error' });
    return;
  }

  // const { arn, assumedRoleUser } = loginResult?.body?.assumedRoleUser || {};
  const { accessKeyId, accessKeySecret, securityToken, expiration } = credentials || {};

  // get aliyun signing token
  const signingUrl = 'https://signin.aliyun.com/federation';

  const params = new URLSearchParams();
  params.append('Action', 'GetSigninToken');
  params.append('AccessKeyId', accessKeyId);
  params.append('AccessKeySecret', accessKeySecret);
  params.append('SecurityToken', securityToken);
  params.append('TicketType', 'mini');

  const signingResult = await fetch(signingUrl, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
    },
    body: params,
  });

  const result = await signingResult?.json?.();

  res.json({ data: result?.SigninToken || '' });
});

// All other GET requests not handled before will return our React app
app.get('*', (req, res) => {
  res.sendFile(path.resolve(__dirname, './client/dist', 'index.html'));
});

const httpServer = http.createServer(app);
const httpsServer = https.createServer(credentials, app);

httpServer.listen(8080);
httpsServer.listen(8443);

console.log('express running at http://localhost:%d', 8080);
  • loginAliyun.js
'use strict';
// This file is auto-generated, don't edit it
// 依赖的模块可通过下载工程中的模块依赖文件或右上角的获取 SDK 依赖信息查看
const Sts20150401 = require('@alicloud/sts20150401');
const OpenApi = require('@alicloud/openapi-client');
const Util = require('@alicloud/tea-util');
const Tea = require('@alicloud/tea-typescript');

// https://api.aliyun.com/api/Sts/2015-04-01/AssumeRole?lang=NODEJS
class Client {

  /**
   * 使用AK&SK初始化账号Client
   * @return Client
   * @throws Exception
   */
  static createClient(accessKeyId, accessKeySecret, regionId) {
    // 工程代码泄露可能会导致 AccessKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考。
    // 建议使用更安全的 STS 方式,更多鉴权访问方式请参见:https://help.aliyun.com/document_detail/378664.html。
    let config = new OpenApi.Config({
      // 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID。
      accessKeyId: process.env['ALIBABA_CLOUD_ACCESS_KEY_ID'] || accessKeyId,
      // 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
      accessKeySecret: process.env['ALIBABA_CLOUD_ACCESS_KEY_SECRET'] || accessKeySecret,
    });
    // Endpoint 请参考 https://api.aliyun.com/product/Sts
    config.endpoint = `sts.${regionId}.aliyuncs.com`;
    return new Sts20150401.default(config);
  }

  static async main(accessKeyId, accessKeySecret, regionId, roleArn, roleSessionName, durationSeconds) {
    let result;
    let client = Client.createClient(accessKeyId, accessKeySecret, regionId);
    let assumeRoleRequest = new Sts20150401.AssumeRoleRequest({
      roleArn: roleArn,
      roleSessionName: roleSessionName || 'ram',
      durationSeconds: durationSeconds || 3600, // 有效期,单位为秒
    });
    let runtime = new Util.RuntimeOptions({});
    try {
      // 复制代码运行请自行打印 API 的返回值
      result = await client.assumeRoleWithOptions(assumeRoleRequest, runtime);
    } catch (error) {
      // 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
      // 错误 message
      console.log(error.message);
      // 诊断地址
      console.log(error.data["Recommend"]);
      Util.default.assertAsString(error.message);
    }
    return result;
  }

}

module.exports = Client;


  • package.json
{
  "name": "aliyun-iframe-dataworks-server",
  "version": "1.0.0",
  "description": "Aliyun Iframe DataWorks",
  "private": true,
  "main": "/pages/index.html",
  "scripts": {
    "start": "node index.js"
  },
  "dependencies": {
    "@alicloud/openapi-client": "0.4.7",
    "@alicloud/sts20150401": "1.1.3",
    "@alicloud/tea-typescript": "1.8.0",
    "@alicloud/tea-util": "1.4.7",
    "express": "4.17.1",
    "node-fetch": "2.7.0",
    "path": "^0.12.7"
  },
  "engines": {
    "node": ">=16.16.0"
  }
}


  • client/dist/index.html
<!DOCTYPE html>

<head>
  <style>
    #url-input {
      width: 600px;
    }

    iframe {
      margin: 16px;
      width: calc(100% - 32px);
      height: 680px;
    }
  </style>
  <script>
    window.fetchSigninToken = async () => {
      let result = '';
      try {
        const response = await fetch('/getSigninToken');
        const json = await response?.json?.();
        result = json?.data;
      } catch (e) {
        console.error(e);
      }
      return result;
    };
    window.onUrlChange = async () => {
      try {
        const url = document.getElementById('url-input').value;
        if (!url) return;
        const signinToken = await fetchSigninToken();
        if (!signinToken) return;
        const encodedLoginUrl = encodeURIComponent('https://signin.aliyun.com');
        const encodedUrl = encodeURIComponent(url);
        const encodedSinginToken = encodeURIComponent(signinToken);
        const iframe = document.getElementById('iframe-web');
        iframe.src = `https://signin.aliyun.com/federation?Action=Login&LoginUrl=${encodedLoginUrl}&Destination=${encodedUrl}&SigninToken=${encodedSinginToken}`;
      } catch (e) {
        console.error(e);
      }
    };
  </script>
</head>

<body>
  <div id="message"></div>
  嵌入的页面:
  <span>URL: </span><input id="url-input" type="text" />
  <button onclick="onUrlChange();">刷新</button>
  <div>
    <iframe id="iframe-web" frameBorder="0"></iframe>
  </div>
</body>


  • sslcert 文件夹下新建 example.com.crt 与 example.com.key


修改 index.js 以下部份:


const regionId = 'cn-shanghai'; // 要登录 DataWorks 的地域
const ramAccessKeyId = 'your ram access key id'; // RAM 帐户的 Access Key Id
const ramAccessKeySecret = 'your ram access key secret'; // RAM 帐户的 Access Key Secret
const roleArn = 'role arn'; // 角色 ARN



执行以下指令:

yarn install # 安装依赖
yarn start


打开路径 https://localhost:8443/,并填入要嵌入的页面链接

image.png



小结与后续

STS 令牌服务登录业务是阿里云提供的嵌入方式,其它业务如 OpenTelemetry、嵌入管控台也都是使用此方法,但使用此方法后,仍有一些问题需要解决:


  • 被嵌入的业务方,需提供可嵌入的功能模块、链接格式、可提供的参数透出给接入方
  • 被嵌入的业务模块,需要隐藏如公共头、侧边栏以及不必要的跳转,也需要被嵌入的业务方来调整
  • 当使用 RAM 帐号透过 STS 令牌服务登录 DataWorks 后,若单独打开 DataWorks 链接也会是登录状态,其原因是因为 STS 令牌服务的登录失效时间与 DataWorks 登录失效时间不一致导致,后续若统一调整为阿里云登录失效时间后,此问题可解
  • 虽然我们只给 RAM 帐号 AliyunSTSAssumeRoleAccess 的权限,但是仍需要接入方在自建的 Web 系统上,将自营的帐号一对一对应到 RAM 帐号或 Role,让每个登录到自建的 Web 的用户,都是独立使用一个 RAM 帐号或 Role (不使用共享一个帐号或 Role 的方式),提高安全性
  • 确保每次都能完整初始化 DataWorks 页面,可在背景 (隐藏 iframe) 先嵌入完整页面如 https://dataworks4service.data.aliyun.com/cn-shanghai/dmc,再将 iframe 链接调整至功能模块 (血缘图)




相关实践学习
基于MaxCompute的热门话题分析
本实验围绕社交用户发布的文章做了详尽的分析,通过分析能得到用户群体年龄分布,性别分布,地理位置分布,以及热门话题的热度。
一站式大数据开发治理平台DataWorks初级课程
DataWorks 从 2009 年开始,十ー年里一直支持阿里巴巴集团内部数据中台的建设,2019 年双 11 稳定支撑每日千万级的任务调度。每天阿里巴巴内部有数万名数据和算法工程师正在使用DataWorks,承了阿里巴巴 99%的据业务构建。本课程主要介绍了阿里巴巴大数据技术发展历程与 DataWorks 几大模块的基本能力。 课程目标 &nbsp;通过讲师的详细讲解与实际演示,学员可以一边学习一边进行实际操作,可以深入了解DataWorks各大模块的使用方式和具体功能,让学员对DataWorks数据集成、开发、分析、运维、安全、治理等方面有深刻的了解,加深对阿里云大数据产品体系的理解与认识。 适合人群 &nbsp;企业数据仓库开发人员 &nbsp;大数据平台开发人员 &nbsp;数据分析师 &nbsp;大数据运维人员 &nbsp;对于大数据平台、数据中台产品感兴趣的开发者
目录
相关文章
|
1月前
|
Java API 数据库
构建RESTful API已经成为现代Web开发的标准做法之一。Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐。
【10月更文挑战第11天】本文介绍如何使用Spring Boot构建在线图书管理系统的RESTful API。通过创建Spring Boot项目,定义`Book`实体类、`BookRepository`接口和`BookService`服务类,最后实现`BookController`控制器来处理HTTP请求,展示了从基础环境搭建到API测试的完整过程。
42 4
|
9天前
|
人工智能 关系型数据库 MySQL
数据魔力,一触即发 —— Dataphin数据服务API,百炼插件新星降临!
本文通过一个利用百炼大模型平台和Dataphin数据服务API构建一个客户360智能应用的案例,介绍如何使用Dataphin数据服务API在百炼平台创建一个自定义插件,用于智能应用的开发,提升企业智能化应用水平。
数据魔力,一触即发 —— Dataphin数据服务API,百炼插件新星降临!
|
6天前
|
XML 数据可视化 API
商品详情数据实战案例,API接口系列
淘宝商品详情数据在电商领域具有广泛的应用价值,而淘宝商品详情API接口则为开发者提供了获取这些数据的重要途径。通过合理利用这些接口和数据,可以提升业务效率、优化用户体验,为电商行业的发展注入新的活力。
|
10天前
|
SQL 缓存 API
在API接口数据获取过程中,如何确保数据的安全性和隐私性?
在API接口数据获取过程中,确保数据的安全性和隐私性至关重要。本文介绍了身份认证与授权、防止SQL注入和XSS攻击、加密传输、API版本控制、限流与熔断、压力测试与性能优化、备份与恢复以及法律和伦理考量等关键措施,帮助开发者和管理者有效保护API接口的数据安全和隐私性。
|
11天前
|
前端开发 API 开发者
Python Web开发者必看!AJAX、Fetch API实战技巧,让前后端交互如丝般顺滑!
在Web开发中,前后端的高效交互是提升用户体验的关键。本文通过一个基于Flask框架的博客系统实战案例,详细介绍了如何使用AJAX和Fetch API实现不刷新页面查看评论的功能。从后端路由设置到前端请求处理,全面展示了这两种技术的应用技巧,帮助Python Web开发者提升项目质量和开发效率。
25 1
|
17天前
|
前端开发 JavaScript API
探索GraphQL:如何构建高效的数据API
【10月更文挑战第25天】在现代Web开发中,API的效率和灵活性至关重要。本文探讨了如何利用GraphQL构建高效的数据API。GraphQL通过声明式查询方式,允许客户端精确指定所需数据,减少数据传输量,提高API效率。文章介绍了设置GraphQL服务器、设计API Schema、实现解析函数及调整前后端交互的具体步骤,展示了GraphQL的优势和应用场景。
31 2
|
17天前
|
JSON API 数据格式
如何使用Python和Flask构建一个简单的RESTful API。Flask是一个轻量级的Web框架
本文介绍了如何使用Python和Flask构建一个简单的RESTful API。Flask是一个轻量级的Web框架,适合小型项目和微服务。文章从环境准备、创建基本Flask应用、定义资源和路由、请求和响应处理、错误处理等方面进行了详细说明,并提供了示例代码。通过这些步骤,读者可以快速上手构建自己的RESTful API。
25 2
|
22天前
|
缓存 监控 测试技术
获取API接口数据的最佳实践详解
在开发过程中,与API进行交互是获取数据和服务的关键步骤。本文详细介绍了10个最佳实践,包括明确需求和文档、错误处理、数据验证、性能优化、安全性、日志和监控、版本控制、代码复用和维护、测试以及遵守法律和道德规范,帮助开发者更高效地从API获取数据,确保数据的准确性、安全性和性能。
|
21天前
|
存储 数据可视化 API
API接口数据获取流程的细化
本文概述了API的基础知识、获取API访问权限的方法、编写代码调用API的步骤、数据处理与分析技巧以及数据安全与合规的重要性,并提供了社交媒体数据分析、天气预报应用和电商数据分析等API数据获取的应用实例,旨在帮助读者全面了解和实践API接口数据获取的流程。
|
21天前
|
缓存 监控 API
抖音抖店 API 请求获取宝贝详情数据的调用频率限制如何调整?
抖音抖店API请求获取宝贝详情数据的调用频率受限,需遵循平台规则。开发者可通过提升账号等级、申请更高配额、优化业务逻辑(如缓存数据、异步处理、批量请求)及监控调整等方式来应对。

相关产品

  • 大数据开发治理平台 DataWorks