為匿名 (未註冊) 使用者嵌入 QuickSight 儀表板 - Amazon QuickSight

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

為匿名 (未註冊) 使用者嵌入 QuickSight 儀表板

重要

Amazon QuickSight 具有用於內嵌分析的新 API 操作:GenerateEmbedUrlForAnonymousUserGenerateEmbedUrlForRegisteredUser

您仍然可以使用 GetDashboardEmbedUrlGetSessionEmbedUrl API 操作內嵌儀表板和 QuickSight 主控台,但它們不包含最新的內嵌功能。如需使用舊 API 操作進行內嵌的詳細資訊,請參閱 使用 GetDashboardEmbedURL 和 GetSessionEmbedURL API 操作內嵌分析

 適用於:企業版本 
   目標受眾:Amazon QuickSight 開發人員 

在以下章節中,您可以找到有關如何為匿名 (未注冊) 使用者設定內嵌式 Amazon QuickSight 儀表板的詳細資訊。

步驟 1:設定許可

 適用於:企業版本 
   目標受眾:Amazon QuickSight 開發人員 

在以下章節中,您可以了解如何為後端應用程式或 Web 伺服器設定許可。這個任務需要有 IAM 的管理存取權。

存取儀表板的每個使用者,都必須擔任一個賦予他們 Amazon QuickSight 存取權和儀表板許可的角色。為了實現這一點,請在您的 AWS 帳戶中建立 IAM 角色。將 IAM 政策與此角色建立關聯,以提供許可給擔任此角色的任何使用者。

您可以在 IAM 政策中建立條件,以限制開發人員可在 GenerateEmbedUrlForAnonymousUser API 操作的 AllowedDomains 參數中列出的域。AllowedDomains 參數是選用參數。它會授予您身為開發人員的選項,讓您可以覆寫管理 QuickSight 選單中設定的靜態域。您則最多可以列出三個可存取產生之 URL 的域或子網域。然後,此 URL 將嵌入您建立的網站中。只有參數中列出的域可以存取內嵌式儀表板。如果沒有這種情況,您可以在 AllowedDomains 參數中列出網際網路上的任何域。

若要限制開發人員可搭配此參數使用的域,請在 IAM 政策中新增 AllowedEmbeddingDomains 條件。如需有關 AllowedDomains 參數的詳細資訊,請參閱https://docs.aws.amazon.com/quicksight/latest/APIReference/API_GenerateEmbedUrlForAnonymousUser.html《Amazon QuickSight API 參考》中的 GenerateEmbedUrlForAnonymousUser

下列範例政策提供搭配 GenerateEmbedUrlForAnonymousUser 使用的許可。若要使這種方法生效,您的 AWS 帳戶還需要一個工作階段套件。或工作階段容量定價。否則,當使用者嘗試存取儀表板時,會傳回錯誤 UnsupportedPricingPlanException

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "quicksight:GenerateEmbedUrlForAnonymousUser" ], "Resource": [ "arn:{{partition}}:quicksight:{{region}}:{{accountId}}:namespace/{{namespace}}", "arn:{{partition}}:quicksight:{{region}}:{{accountId}}:dashboard/{{dashboardId-1}}", "arn:{{partition}}:quicksight:{{region}}:{{accountId}}:dashboard/{{dashboardId-2}}" ], "Condition": { "ForAllValues:StringEquals": { "quicksight:AllowedEmbeddingDomains": [ "https://my.static.domain1.com", "https://*.my.static.domain2.com" ] } } }

您的應用程式的 IAM 身分必須有相關聯的信任政策,以允許存取至您剛建立的角色。這表示當使用者存取您的應用程式時,您的應用程式可代表使用者擔任該角色,並開啟儀表板。範例信任政策如下所示。

{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowLambdaFunctionsToAssumeThisRole", "Effect": "Allow", "Principal": { "Service": "lambda.amazonaws.com" }, "Action": "sts:AssumeRole" }, { "Sid": "AllowEC2InstancesToAssumeThisRole", "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }

如需有關信任政策的詳細資訊,請參閱《IAM 使用者指南》中的 IAM 中的臨時安全憑證

步驟 2:產生帶有身分驗證碼的 URL

 適用於:企業版本 
   目標受眾:Amazon QuickSight 開發人員 

在下一章節,您可以了解如何在您的應用程式伺服器上代表匿名訪客進行身分驗證,以及取得可內嵌的儀表板 URL。

當使用者存取您的應用程式時,該應用程式代表使用者擔任 IAM 角色。然後,如果該使用者尚未存在,則它將使用者新增至 QuickSight。接著,它傳遞識別符當作唯一的角色工作階段 ID。

下列範例會代表使用者執行 IAM 身分驗證。它傳遞識別符當作唯一的角色工作階段 ID。此代碼在您的應用程式伺服器上運行。

import java.util.List; import com.amazonaws.auth.AWSCredentials; import com.amazonaws.auth.AWSCredentialsProvider; import com.amazonaws.auth.BasicAWSCredentials; import com.amazonaws.regions.Regions; import com.amazonaws.services.quicksight.AmazonQuickSight; import com.amazonaws.services.quicksight.AmazonQuickSightClientBuilder; import com.amazonaws.services.quicksight.model.RegisteredUserDashboardEmbeddingConfiguration; import com.amazonaws.services.quicksight.model.AnonymousUserEmbeddingExperienceConfiguration; import com.amazonaws.services.quicksight.model.GenerateEmbedUrlForAnonymousUserRequest; import com.amazonaws.services.quicksight.model.GenerateEmbedUrlForAnonymousUserResult; import com.amazonaws.services.quicksight.model.SessionTag; /** * Class to call QuickSight AWS SDK to generate embed url for anonymous user. */ public class GenerateEmbedUrlForAnonymousUserExample { private final AmazonQuickSight quickSightClient; public GenerateEmbedUrlForAnonymousUserExample() { quickSightClient = AmazonQuickSightClientBuilder .standard() .withRegion(Regions.US_EAST_1.getName()) .withCredentials(new AWSCredentialsProvider() { @Override public AWSCredentials getCredentials() { // provide actual IAM access key and secret key here return new BasicAWSCredentials("access-key", "secret-key"); } @Override public void refresh() { } } ) .build(); } public String GenerateEmbedUrlForAnonymousUser( final String accountId, // YOUR AWS ACCOUNT ID final String initialDashboardId, // DASHBOARD ID TO WHICH THE CONSTRUCTED URL POINTS. final String namespace, // ANONYMOUS EMBEDDING REQUIRES SPECIFYING A VALID NAMESPACE FOR WHICH YOU WANT THE EMBEDDING URL final List<String> authorizedResourceArns, // DASHBOARD ARN LIST TO EMBED final List<String> allowedDomains, // RUNTIME ALLOWED DOMAINS FOR EMBEDDING final List<SessionTag> sessionTags // SESSION TAGS USED FOR ROW-LEVEL SECURITY ) throws Exception { AnonymousUserEmbeddingExperienceConfiguration experienceConfiguration = new AnonymousUserEmbeddingExperienceConfiguration(); AnonymousUserDashboardEmbeddingConfiguration dashboardConfiguration = new AnonymousUserDashboardEmbeddingConfiguration(); dashboardConfiguration.setInitialDashboardId(initialDashboardId); experienceConfiguration.setDashboard(dashboardConfiguration); GenerateEmbedUrlForAnonymousUserRequest generateEmbedUrlForAnonymousUserRequest = new GenerateEmbedUrlForAnonymousUserRequest() .withAwsAccountId(accountId) .withNamespace(namespace) .withAuthorizedResourceArns(authorizedResourceArns) .withExperienceConfiguration(experienceConfiguration) .withSessionTags(sessionTags) .withSessionLifetimeInMinutes(600L); // OPTIONAL: VALUE CAN BE [15-600]. DEFAULT: 600 .withAllowedDomains(allowedDomains); GenerateEmbedUrlForAnonymousUserResult dashboardEmbedUrl = quickSightClient.generateEmbedUrlForAnonymousUser(generateEmbedUrlForAnonymousUserRequest); return dashboardEmbedUrl.getEmbedUrl(); } }
global.fetch = require('node-fetch'); const AWS = require('aws-sdk'); function generateEmbedUrlForAnonymousUser( accountId, // YOUR AWS ACCOUNT ID initialDashboardId, // DASHBOARD ID TO WHICH THE CONSTRUCTED URL POINTS quicksightNamespace, // VALID NAMESPACE WHERE YOU WANT TO DO NOAUTH EMBEDDING authorizedResourceArns, // DASHBOARD ARN LIST TO EMBED allowedDomains, // RUNTIME ALLOWED DOMAINS FOR EMBEDDING sessionTags, // SESSION TAGS USED FOR ROW-LEVEL SECURITY generateEmbedUrlForAnonymousUserCallback, // GENERATEEMBEDURLFORANONYMOUSUSER SUCCESS CALLBACK METHOD errorCallback // GENERATEEMBEDURLFORANONYMOUSUSER ERROR CALLBACK METHOD ) { const experienceConfiguration = { "DashboardVisual": { "InitialDashboardVisualId": { "DashboardId": "dashboard_id", "SheetId": "sheet_id", "VisualId": "visual_id" } } }; const generateEmbedUrlForAnonymousUserParams = { "AwsAccountId": accountId, "Namespace": quicksightNamespace, "AuthorizedResourceArns": authorizedResourceArns, "AllowedDomains": allowedDomains, "ExperienceConfiguration": experienceConfiguration, "SessionTags": sessionTags, "SessionLifetimeInMinutes": 600 }; const quicksightClient = new AWS.QuickSight({ region: process.env.AWS_REGION, credentials: { accessKeyId: AccessKeyId, secretAccessKey: SecretAccessKey, sessionToken: SessionToken, expiration: Expiration } }); quicksightClient.generateEmbedUrlForAnonymousUser(generateEmbedUrlForAnonymousUserParams, function(err, data) { if (err) { console.log(err, err.stack); errorCallback(err); } else { const result = { "statusCode": 200, "headers": { "Access-Control-Allow-Origin": "*", // USE YOUR WEBSITE DOMAIN TO SECURE ACCESS TO THIS API "Access-Control-Allow-Headers": "Content-Type" }, "body": JSON.stringify(data), "isBase64Encoded": false } generateEmbedUrlForAnonymousUserCallback(result); } }); }
import json import boto3 from botocore.exceptions import ClientError import time # Create QuickSight and STS clients quicksightClient = boto3.client('quicksight',region_name='us-west-2') sts = boto3.client('sts') # Function to generate embedded URL for anonymous user # accountId: YOUR AWS ACCOUNT ID # quicksightNamespace: VALID NAMESPACE WHERE YOU WANT TO DO NOAUTH EMBEDDING # authorizedResourceArns: DASHBOARD ARN LIST TO EMBED # allowedDomains: RUNTIME ALLOWED DOMAINS FOR EMBEDDING # dashboardId: DASHBOARD ID TO WHICH THE CONSTRUCTED URL POINTS # sessionTags: SESSION TAGS USED FOR ROW-LEVEL SECURITY def generateEmbedUrlForAnonymousUser(accountId, quicksightNamespace, authorizedResourceArns, allowedDomains, dashboardId, sessionTags): try: response = quicksightClient.generate_embed_url_for_anonymous_user( AwsAccountId = accountId, Namespace = quicksightNamespace, AuthorizedResourceArns = authorizedResourceArns, AllowedDomains = allowedDomains, ExperienceConfiguration = { "Dashboard": { "InitialDashboardId": dashboardId } }, SessionTags = sessionTags, SessionLifetimeInMinutes = 600 ) return { 'statusCode': 200, 'headers': {"Access-Control-Allow-Origin": "*", "Access-Control-Allow-Headers": "Content-Type"}, 'body': json.dumps(response), 'isBase64Encoded': bool('false') } except ClientError as e: print(e) return "Error generating embeddedURL: " + str(e)

以下範例顯示的 JavaScript (Node.js) 可在應用程式伺服器上用來產生內嵌式儀表板的 URL。您可以在您的網站或應用程式中使用此 URL 來顯示儀表板。

const AWS = require('aws-sdk'); const https = require('https'); var quicksightClient = new AWS.Service({ apiConfig: require('./quicksight-2018-04-01.min.json'), region: 'us-east-1', }); quicksightClient.generateEmbedUrlForAnonymousUser({ 'AwsAccountId': '111122223333', 'Namespace' : 'default', 'AuthorizedResourceArns': authorizedResourceArns, 'AllowedDomains': allowedDomains, 'ExperienceConfiguration': experienceConfiguration, 'SessionTags': sessionTags, 'SessionLifetimeInMinutes': 600 }, function(err, data) { console.log('Errors: '); console.log(err); console.log('Response: '); console.log(data); });
//The URL returned is over 900 characters. For this example, we've shortened the string for //readability and added ellipsis to indicate that it's incomplete. { Status: 200, EmbedUrl: 'https://quicksightdomain/embed/12345/dashboards/67890..', RequestId: '7bee030e-f191-45c4-97fe-d9faf0e03713' }

以下範例顯示的 .NET/C# 程式碼可在應用程式伺服器上用來產生內嵌式儀表板的 URL。您可以在您的網站或應用程式中使用此 URL 來顯示儀表板。

using System; using Amazon.QuickSight; using Amazon.QuickSight.Model; var quicksightClient = new AmazonQuickSightClient( AccessKey, SecretAccessKey, sessionToken, Amazon.RegionEndpoint.USEast1); try { Console.WriteLine( quicksightClient.GenerateEmbedUrlForAnonymousUserAsync(new GenerateEmbedUrlForAnonymousUserRequest { AwsAccountId = "111122223333", Namespace = default, AuthorizedResourceArns = authorizedResourceArns, AllowedDomains = allowedDomains, ExperienceConfiguration = experienceConfiguration, SessionTags = sessionTags, SessionLifetimeInMinutes = 600, }).Result.EmbedUrl ); } catch (Exception ex) { Console.WriteLine(ex.Message); }

若要擔任角色,請選擇下列其中一個 AWS Security Token Service (AWS STS) API 操作:

  • AssumeRole – 在使用 IAM 身分擔任角色的情況下使用此操作。

  • AssumeRoleWithWebIdentity – 在使用 Web 身分提供者驗證您的使用者時,請使用此操作。

  • AssumeRoleWithSaml –在您使用安全性聲明標記語言 (SAML) 驗證使用者時,請使用此操作。

以下範例顯示用來設定 IAM 角色的 CLI 命令。角色需要啟用 quicksight:GenerateEmbedUrlForAnonymousUser 的許可。

aws sts assume-role \ --role-arn "arn:aws:iam::11112222333:role/QuickSightEmbeddingAnonymousPolicy" \ --role-session-name anonymous caller

assume-role 操作會傳回三個輸出參數:存取金鑰、私密金鑰和工作階段字符。

注意

若您呼叫 AssumeRole 操作時收到 ExpiredToken 錯誤,原因可能是先前的 SESSION TOKEN 仍在環境變數中。設定以下變數便可清除此錯誤:

  • AWS_ACCESS_KEY_ID

  • AWS_SECRET_ACCESS_KEY

  • AWS_SESSION_TOKEN

以下範例說明如何在 CLI 中設定這三個參數。如果您使用 Microsoft Windows 電腦,請使用 set,不要使用 export

export AWS_ACCESS_KEY_ID = "access_key_from_assume_role" export AWS_SECRET_ACCESS_KEY = "secret_key_from_assume_role" export AWS_SESSION_TOKEN = "session_token_from_assume_role"

對於瀏覽您網站的使用者,執行這些命令可將其角色工作階段 ID 設為 embedding_quicksight_dashboard_role/QuickSightEmbeddingAnonymousPolicy。角色工作階段 ID 由來自 role-arnrole-session-name 值的角色名稱所組成。對每個使用者使用唯一的角色工作階段 ID,可確保為每個訪問使用者設定適當的許可。它還使每個會話獨立且不同。如果您正在使用 Web 伺服器陣列 (例如負載平衡),且工作階段重新連線到不同的伺服器,則會開始新的工作階段。

為了取得儀表板的簽章 URL,請從應用程式伺服器呼叫 generate-embed-url-for-anynymous-user。這會傳回可內嵌的儀表板 URL。下列範例會顯示如何使用伺服器端呼叫,針對匿名造訪您的 Web 入口網站或應用程式的使用者,產生內嵌式儀表板的 URL。

aws quicksight generate-embed-url-for-anonymous-user \ --aws-account-id 111122223333 \ --namespace default-or-something-else \ --session-lifetime-in-minutes 15 \ --authorized-resource-arns '["dashboard-arn-1","dashboard-arn-2"]' \ --allowed-domains '["domain1","domain2"]' \ --session-tags '["Key": tag-key-1,"Value": tag-value-1,{"Key": tag-key-1,"Value": tag-value-1}]' \ --experience-configuration 'DashboardVisual={InitialDashboardVisualId={DashboardId=dashboard_id,SheetId=sheet_id,VisualId=visual_id}}'

如需使用此操作的詳細資訊,請參閱 GenerateEmbedUrlForAnonymousUser。您可以在您自己的程式碼中使用這個和其他 API 操作。

步驟 3:內嵌儀表板 URL

 適用於:企業版本 
   目標受眾:Amazon QuickSight 開發人員 

在下一章節,您可以了解如何使用 QuickSight 內嵌開發套件 (JavaScript),將步驟 2 中的儀表板 URL 內嵌於您的網站或應用程式頁面。您可以使用此開發套件執行以下操作:

  • 將儀表板放在 HTML 頁面。

  • 將參數傳遞到儀表板。

  • 以針對您的應用程式而訂做的訊息來處理錯誤狀態。

呼叫 GenerateEmbedUrlForAnynymousUser API 操作以產生可嵌入應用程式的 URL。此 URL 的有效期為 5 分鐘,而產生的工作階段有效期為 10 小時。此 API 操作提供的 URL 附有可啟用單一登入工作階段的 auth_code

以下是 generate-embed-url-for-anynymous-user 的回應範例。

//The URL returned is over 900 characters. For this example, we've shortened the string for //readability and added ellipsis to indicate that it's incomplete. { "Status": "200", "EmbedUrl": "https://quicksightdomain/embed/12345/dashboards/67890..", "RequestId": "7bee030e-f191-45c4-97fe-d9faf0e03713" }

使用 QuickSight 內嵌開發套件,或將此 URL 加到 iframe 中,以將此儀表板內嵌於您的網頁。若您設定固定的高度和寬度數字 (像素),QuickSight 會使用這些值,而不會隨著您調整視窗大小而改變視覺效果。如果您是設定相對百分比高度和寬度,QuickSight 將提供隨視窗大小變更而改變的回應式版面配置。透過使用 QuickSight 內嵌開發套件,您還可以控制儀表板內的參數,並於頁面載入完成及發生錯誤時接收回呼。

要託管內嵌儀表板的網域必須位於允許清單上,即 Amazon QuickSight 訂閱的已核准網域清單。這項要求將使未獲核准的網域無法託管內嵌儀表板,進而保護您的資料。如需為內嵌式儀表板新增域的詳細資訊,請參閱 在執行期使用 QuickSight API 將域新增至允許清單

下列範例示範如何使用產生的 URL。此代碼駐留在您的應用程式伺服器上。

<!DOCTYPE html> <html> <head> <title>Dashboard Embedding Example</title> <script src="https://unpkg.com/amazon-quicksight-embedding-sdk@2.0.0/dist/quicksight-embedding-js-sdk.min.js"></script> <script type="text/javascript"> const embedDashboard = async() => { const { createEmbeddingContext, } = QuickSightEmbedding; const embeddingContext = await createEmbeddingContext({ onChange: (changeEvent, metadata) => { console.log('Context received a change', changeEvent, metadata); }, }); const frameOptions = { url: '<YOUR_EMBED_URL>', container: '#experience-container', height: "700px", width: "1000px", onChange: (changeEvent, metadata) => { switch (changeEvent.eventName) { case 'FRAME_MOUNTED': { console.log("Do something when the experience frame is mounted."); break; } case 'FRAME_LOADED': { console.log("Do something when the experience frame is loaded."); break; } } }, }; const contentOptions = { parameters: [ { Name: 'country', Values: [ 'United States' ], }, { Name: 'states', Values: [ 'California', 'Washington' ] } ], locale: "en-US", sheetOptions: { initialSheetId: '<YOUR_SHEETID>', singleSheet: false, emitSizeChangedEventOnSheetChange: false, }, toolbarOptions: { export: false, undoRedo: false, reset: false }, attributionOptions: { overlayContent: false, }, onMessage: async (messageEvent, experienceMetadata) => { switch (messageEvent.eventName) { case 'CONTENT_LOADED': { console.log("All visuals are loaded. The title of the document:", messageEvent.message.title); break; } case 'ERROR_OCCURRED': { console.log("Error occurred while rendering the experience. Error code:", messageEvent.message.errorCode); break; } case 'PARAMETERS_CHANGED': { console.log("Parameters changed. Changed parameters:", messageEvent.message.changedParameters); break; } case 'SELECTED_SHEET_CHANGED': { console.log("Selected sheet changed. Selected sheet:", messageEvent.message.selectedSheet); break; } case 'SIZE_CHANGED': { console.log("Size changed. New dimensions:", messageEvent.message); break; } case 'MODAL_OPENED': { window.scrollTo({ top: 0 // iframe top position }); break; } } }, }; const embeddedDashboardExperience = await embeddingContext.embedDashboard(frameOptions, contentOptions); const selectCountryElement = document.getElementById('country'); selectCountryElement.addEventListener('change', (event) => { embeddedDashboardExperience.setParameters([ { Name: 'country', Values: event.target.value } ]); }); }; </script> </head> <body onload="embedDashboard()"> <span> <label for="country">Country</label> <select id="country" name="country"> <option value="United States">United States</option> <option value="Mexico">Mexico</option> <option value="Canada">Canada</option> </select> </span> <div id="experience-container"></div> </body> </html>
<!DOCTYPE html> <html> <head> <title>Basic Embed</title> <script src="https://unpkg.com/amazon-quicksight-embedding-sdk@1.0.15/dist/quicksight-embedding-js-sdk.min.js"></script> <script type="text/javascript"> var dashboard function onDashboardLoad(payload) { console.log("Do something when the dashboard is fully loaded."); } function onError(payload) { console.log("Do something when the dashboard fails loading"); } function embedDashboard() { var containerDiv = document.getElementById("embeddingContainer"); var options = { // replace this dummy url with the one generated via embedding API url: "https://us-east-1.quicksight.aws.amazon.com/sn/dashboards/dashboardId?isauthcode=true&identityprovider=quicksight&code=authcode", container: containerDiv, parameters: { country: "United States" }, scrolling: "no", height: "700px", width: "1000px", locale: "en-US", footerPaddingEnabled: true }; dashboard = QuickSightEmbedding.embedDashboard(options); dashboard.on("error", onError); dashboard.on("load", onDashboardLoad); } function onCountryChange(obj) { dashboard.setParameters({country: obj.value}); } </script> </head> <body onload="embedDashboard()"> <span> <label for="country">Country</label> <select id="country" name="country" onchange="onCountryChange(this)"> <option value="United States">United States</option> <option value="Mexico">Mexico</option> <option value="Canada">Canada</option> </select> </span> <div id="embeddingContainer"></div> </body> </html>

若要使此範例生效,請務必使用 QuickSight 內嵌開發套件,在您使用 JavaScript 的網站上載入內嵌式儀表板。為獲得您的版本,請執行以下其中一項操作: