GitHub 连接器示例
GitHub M 扩展演示如何添加对 OAuth 2.0 协议身份验证流的支持。 你可以在 GitHub 开发人员站点上了解有关 GitHub 身份验证流的详细信息。
在开始创建 M 扩展之前,你需要在 GitHub 上注册新应用,并将 client_id
和 client_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 应用程序。
Application name
:输入 M 扩展的应用程序的名称。Authorization callback URL
:输入 https://oauth.powerbi.com/views/oauthredirect.html。Scope
:在 GitHub 中,将范围设置为user, repo
。
注意
注册的 OAuth 应用程序都分配有一个唯一的客户端 ID 和客户端密码。 不应共享客户端密码。 你可以从 GitHub 应用程序页面中获取客户端 ID 和客户端密码。 使用客户端 ID(client_id
文件)和客户端密码(client_secret
文件)更新数据连接器项目中的文件。
如何实现 GitHub OAuth
此示例将引导你完成以下步骤:
- 创建声明其支持 OAuth 的数据源种类定义。
- 提供详细信息,以便 M 引擎可以启动 OAuth 流 (
StartLogin
)。 - 将从 GitHub 中接收的代码转换为 access_token(
FinishLogin
和TokenMethod
)。 - 定义访问 GitHub API (
GithubSample.Contents
) 的函数。
步骤 1 - 创建数据源定义
数据连接器以描述扩展的记录开头,包括其唯一名称(即记录的名称)、支持的身份验证类型和数据源的友好显示名称(标签)。
支持 OAuth 时,此定义包含实现 OAuth 协定的函数,在本例中是 StartLogin
和 FinishLogin
。
//
// 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
函数采用一个 resourceUrl
和 state
display
值。
在此函数中,创建一个使用以下参数连接 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( Where
|
标头 | 一条包含 HTTP 请求的其他标头的记录。 | Headers= [ |
此代码片段介绍如何实现 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.Contents
和 GithubSample.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")