GitHub 连接器示例

GitHub M 扩展演示如何添加对 OAuth 2.0 协议身份验证流的支持。 你可以在 GitHub 开发人员站点上了解有关 GitHub 身份验证流的详细信息。

在开始创建 M 扩展之前,你需要在 GitHub 上注册新应用,并将 client_idclient_secret 文件替换为应用的相应值。

有关 Visual Studio 中的兼容性的问题:Power Query SDK 使用基于 Internet Explorer 的控件来弹出 OAuth 对话框。GitHub 已不再支持此控件所使用的 IE 版本,如果从 Visual Studio 中运行,这将阻止你完成为应用授予权限。另一种方法是使用 Power BI Desktop 加载扩展并在那里完成第一个 OAuth 流。在应用程序被授予对你帐户的访问权限后,以后可以从 Visual Studio 正常登录。

OAuth 和 Power BI

OAuth 是一种凭据委派形式。 通过登录到 GitHub 并为你针对 GitHub 创建的“应用程序”授权,用户允许你的“应用程序”代表他们登录,以将数据检索到 Power BI 中。 必须向“应用程序”授予检索数据(获取 access_token)以及按计划刷新数据(获取和使用 refresh_token)的权限。 此上下文中的“应用程序”是用于在 Power BI 中运行查询的数据连接器。 Power BI 会代表你存储和管理 access_token 和 refresh_token。

注意

若要允许 Power BI 获取和使用 access_token,必须将重定向 URL 指定为 https://oauth.powerbi.com/views/oauthredirect.html

当你指定此 URL 并且 GitHub 成功进行身份验证并授予权限时,GitHub 将重定向到 PowerBI 的 oauthredirect 终结点,以便 Power BI 可以检索 access_token 和 refresh_token。

如何注册 GitHub 应用

Power BI 扩展需要登录到 GitHub。 若要启用此功能,请在 https://github.com/settings/applications/new 中向 GitHub 注册新的 OAuth 应用程序。

  1. Application name:输入 M 扩展的应用程序的名称。
  2. Authorization callback URL:输入 https://oauth.powerbi.com/views/oauthredirect.html
  3. Scope:在 GitHub 中,将范围设置为 user, repo

注意

注册的 OAuth 应用程序都分配有一个唯一的客户端 ID 和客户端密码。 不应共享客户端密码。 你可以从 GitHub 应用程序页面中获取客户端 ID 和客户端密码。 使用客户端 ID(client_id 文件)和客户端密码(client_secret 文件)更新数据连接器项目中的文件。

如何实现 GitHub OAuth

此示例将引导你完成以下步骤:

  1. 创建声明其支持 OAuth 的数据源种类定义。
  2. 提供详细信息,以便 M 引擎可以启动 OAuth 流 (StartLogin)。
  3. 将从 GitHub 中接收的代码转换为 access_token(FinishLoginTokenMethod)。
  4. 定义访问 GitHub API (GithubSample.Contents) 的函数。

步骤 1 - 创建数据源定义

数据连接器以描述扩展的记录开头,包括其唯一名称(即记录的名称)、支持的身份验证类型和数据源的友好显示名称(标签)。 支持 OAuth 时,此定义包含实现 OAuth 协定的函数,在本例中是 StartLoginFinishLogin

//
// Data Source definition
//
GithubSample = [
    Authentication = [
        OAuth = [
            StartLogin = StartLogin,
            FinishLogin = FinishLogin
        ]
    ],
    Label = Extension.LoadString("DataSourceLabel")
];

步骤 2 - 提供详细信息,以便 M 引擎可以启动 OAuth 流

将用户定向到 https://github.com/login/oauth/authorize 页面时,GitHub OAuth 流将启动。 为了让用户登录,你需要指定多个查询参数:

名称 Type 描述
client_id string 必需。 注册时从 GitHub 收到的客户端 ID。
redirect_uri string 用户获得授权后被发送到的应用中的 URL。 请参阅以下有关重定向 URL 的详细信息。 对于 M 扩展,redirect_uri 必须为“https://oauth.powerbi.com/views/oauthredirect.html"”。
scope string 作用域的逗号分隔列表。 如果未提供,则作用域默认为无有效应用令牌的用户的空作用域列表。 对于已经拥有有效的应用令牌的用户,不会显示含作用域列表的 OAuth 授权页面。 相反,该流的此步骤将自动完成,其作用域与用户上次完成流时使用的作用域相同。
state string 不可猜测的随机字符串。 它用于防止跨站请求伪造攻击。

以下代码片段介绍如何实现 StartLogin 函数以启动登录流。 StartLogin 函数采用一个 resourceUrlstatedisplay 值。 在此函数中,创建一个使用以下参数连接 GitHub 授权 URL 的 AuthorizeUrl

  • client_id:从 GitHub 应用程序页面向 GitHub 注册扩展后,你将获得客户端 ID。
  • scope:将作用域设置为“user, repo”。 这会为用户设置授权范围(即应用想要访问的内容)。
  • state:M 引擎传入的内部值。
  • redirect_uri:设置为 https://oauth.powerbi.com/views/oauthredirect.html
StartLogin = (resourceUrl, state, display) =>
        let
            AuthorizeUrl = "https://github.com/login/oauth/authorize?" & Uri.BuildQueryString([
                client_id = client_id,
                scope = "user, repo",
                state = state,
                redirect_uri = redirect_uri])
        in
            [
                LoginUri = AuthorizeUrl,
                CallbackUri = redirect_uri,
                WindowHeight = windowHeight,
                WindowWidth = windowWidth,
                Context = null
            ];

如果这是用户第一次使用你的应用登录(由其 client_id 值标识),那么他们将看到一个页面,要求他们向你的应用授予访问权限。 以后尝试登录时只会请求其凭据。

步骤 3 - 将从 GitHub 中接收的代码转换为 access_token

如果用户完成身份验证流,则 GitHub 会使用 code 参数中的临时代码以及你在上一步的 state 参数中提供的状态重定向回 Power BI 重定向 URL。 FinishLogin 函数将从 callbackUri 参数中提取代码,然后用其换取访问令牌(使用 TokenMethod 函数)。

FinishLogin = (context, callbackUri, state) =>
    let
        Parts = Uri.Parts(callbackUri)[Query]
    in
        TokenMethod(Parts[code]);

若要获取 GitHub 访问令牌,你可以从“GitHub 授权响应”传递临时代码。 在 TokenMethod 函数中,你创建了对 GitHub 的 access_token 终结点的 POST 请求 (https://github.com/login/oauth/access_token)。 GitHub 终结点需要以下参数:

名称 Type 描述
client_id string 必需。 注册时从 GitHub 收到的客户端 ID。
client_secret string 必需。 注册时从 GitHub 收到的客户端密码。
code string 必需。 你在 FinishLogin 中收到的代码。
redirect_uri string 用户获得授权后被发送到的应用中的 URL。 请参阅以下有关重定向 URL 的详细信息。

下面是用于 Web.Contents 调用的详细信息参数。

参数 说明
url Web 站点的 URL。 https://github.com/login/oauth/access_token
选项 用于控制此函数的行为的记录。 未在本案例中使用
查询 以编程方式将查询参数添加到 URL 中。 Content = Text.ToBinary(
Uri.BuildQueryString(
[
client_id = client_id,
client_secret = client_secret,
code = code,
redirect_uri = redirect_uri
]
))

Where
  • client_id:GitHub 应用程序页面中的客户端 ID。
  • client_secret:GitHub 应用程序页面中的客户端密码。
  • code:GitHub 授权响应中的代码。
  • redirect_uri:用户获得授权后被发送到的应用中的 URL。
标头 一条包含 HTTP 请求的其他标头的记录。 Headers= [
#"Content-type" = "application/x-www-form-urlencoded",
#"Accept" = "application/json"
]

此代码片段介绍如何实现 TokenMethod 函数以使用授权代码换取访问令牌。

TokenMethod = (code) =>
    let
        Response = Web.Contents("https://Github.com/login/oauth/access_token", [
            Content = Text.ToBinary(Uri.BuildQueryString([
                client_id = client_id,
                client_secret = client_secret,
                code = code,
                redirect_uri = redirect_uri])),
            Headers=[#"Content-type" = "application/x-www-form-urlencoded",#"Accept" = "application/json"]]),
        Parts = Json.Document(Response)
    in
        Parts;

服务的 JSON 响应将包含 access_token 字段。 TokenMethod 方法使用 Json.Document 将 JSON 响应转换为 M 记录,并将其返回到引擎。

示例响应:

{
    "access_token":"e72e16c7e42f292c6912e7710c838347ae178b4a",
    "scope":"user,repo",
    "token_type":"bearer"
}

步骤 4 - 定义访问 GitHub API 的函数

以下代码片段通过将两个函数(GithubSample.ContentsGithubSample.PagedTable)标记为 shared 来导出这两个函数,并将其与 GithubSample 数据源类型关联。

[DataSource.Kind="GithubSample", Publish="GithubSample.UI"]
shared GithubSample.Contents = Value.ReplaceType(Github.Contents, type function (url as Uri.Type) as any);

[DataSource.Kind="GithubSample"]
shared GithubSample.PagedTable = Value.ReplaceType(Github.PagedTable, type function (url as Uri.Type) as nullable table);

GithubSample.Contents 函数也发布到了 UI 中(允许它出现在获取数据对话框中)。 Value.ReplaceType 函数用于将函数参数设置为 Url.Type 归属类型。

通过将这些函数与 GithubSample 数据源种类关联,它们将自动使用用户提供的凭据。 任何已为可扩展性启用的 M 库函数(例如 Web.Contents)也将自动继承这些凭据。

有关凭据和身份验证的工作原理的详细信息,请参阅处理身份验证

示例 URL

此连接器能够从任何 GitHub v3 REST API 终结点中检索带格式的数据。 例如,将所有提交拉取到数据连接器存储库的查询如下所示:

GithubSample.Contents("https://api.github.com/repos/microsoft/dataconnectors/commits")