GitHub M 扩展演示如何添加对 OAuth 2.0 协议身份验证流的支持。 可以在 GitHub Docs 站点上了解有关 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 将重定向到 Power BI 的 oauthredirect 终结点,以便 Power BI 可以检索access_token和refresh_token。
如何注册 GitHub 应用
Power BI 扩展需要登录到 GitHub。 若要启用此功能,请在 GitHub 处 https://github.com/settings/applications/new注册新的 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 流将启动。
若要使用户登录,需要指定多个查询参数:
| Name | 类型 | Description |
|---|---|---|
| 客户编号 | 字符串 | 必需。 注册时从 GitHub 收到的客户端 ID。 |
| 重定向URI | 字符串 | 在应用中,用户授权之后会被发送到的 URL。 请参阅有关重定向 URL 的详细信息。 对于 M 扩展, redirect_uri 必须为“https://oauth.powerbi.com/views/oauthredirect.html"。 |
| 作用域 | 字符串 | 用逗号分隔的范围列表。 如果未提供,则对于没有应用有效令牌的用户,范围默认为空列表。 对于已拥有应用有效令牌的用户,不会显示具有作用域列表的 OAuth 授权页。 在此步骤中,流程将自动完成,使用的权限范围与用户上次完成流程时使用的相同。 |
| 状态 | 字符串 | 不可猜测的随机字符串。 它用于防范跨站点请求伪造攻击。 |
以下代码片段介绍如何实现函数 StartLogin 以启动登录流。
函数StartLogin采用resourceUrl、state和display值。
在这个函数中,创建一个 AuthorizeUrl,它将 GitHub 授权 URL 与以下参数连接起来:
-
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 的访问令牌终结点 (https://github.com/login/oauth/access_token) 构建 POST 请求。
GitHub 终结点需要以下参数:
| Name | 类型 | Description |
|---|---|---|
| 客户编号 | 字符串 | 必需。 注册时从 GitHub 收到的客户端 ID。 |
| client_secret | 字符串 | 必需。 注册时从 GitHub 收到的客户端密码。 |
| 代码 | 字符串 |
必需。 您收到的代码在FinishLogin。 |
| 重定向URI | 字符串 | 授权后用户将被重定向至您应用中的 URL。 请参阅有关重定向 URL 的详细信息。 |
下面是调用 Web.Contents 所用的参数详情。
| 论点 | Description | 价值 |
|---|---|---|
| 网址 | 网站的 URL。 | https://github.com/login/oauth/access_token |
| options | 用于控制此函数行为的记录。 | 本例中未使用 |
| Query | 以编程方式将查询参数添加到 URL。 |
Content = Text.ToBinary()位置
|
| Headers | 包含 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 数据源类型相关联,它们将自动使用用户提供的凭据。 为扩展性(如 Web.Contents)启用的任何 M 库函数也将自动继承这些凭据。
有关凭据和身份验证工作原理的详细信息,请参阅 “处理身份验证”。
示例 URL
此连接器可以从任何 GitHub v3 REST API 终结点检索格式化数据。 例如,将所有提交拉取到数据连接器存储库的查询如下所示:
GithubSample.Contents("https://api.github.com/repos/microsoft/dataconnectors/commits")