如何使用适用于 Azure 移动应用的 Apache Cordova 插件

注意

此产品已停用。 有关使用 .NET 8 或更高版本的项目的替换,请参阅 Community Toolkit Datasync 库

本指南介绍如何使用适用于 Azure 移动应用的最新 Apache Cordova 插件执行常见方案。 如果不熟悉 Azure 移动应用,请先完成 Azure 移动应用快速入门 创建后端、创建表并下载预生成的 Apache Cordova 项目。 本指南重点介绍客户端 Apache Cordova 插件。

支持的平台

此 SDK 支持 iOS、Android 和 Windows 设备上的 Apache Cordova v6.0.0 及更高版本。 平台支持如下所示:

  • Android API 19+。
  • iOS 版本 8.0 及更高版本。

警告

本文介绍已停用的 v4.2.0 库版本的信息。 不会对此库进行进一步更新,包括安全问题的更新。 请考虑迁移到 .NET 客户端(如 .NET MAUI),以便继续支持。

设置和先决条件

本指南假定你已使用表创建了后端。 示例使用快速入门中的 TodoItem 表。 若要将 Azure 移动应用插件添加到项目,请使用以下命令:

cordova plugin add cordova-plugin-ms-azure-mobile-apps

有关创建 第一个 Apache Cordova 应用的详细信息,请参阅其文档。

设置 Ionic v2 应用

若要正确配置 Ionic v2 项目,请先创建一个基本应用并添加 Cordova 插件:

ionic start projectName --v2
cd projectName
ionic plugin add cordova-plugin-ms-azure-mobile-apps

将以下行添加到 app.component.ts 以创建客户端对象:

declare var WindowsAzure: any;
var client = new WindowsAzure.MobileServiceClient("https://yoursite.azurewebsites.net");

现在可以在浏览器中生成并运行项目:

ionic platform add browser
ionic run browser

Azure 移动应用 Cordova 插件支持 Ionic v1 和 v2 应用。 只有 Ionic v2 应用需要 WindowsAzure 对象的额外声明。

创建客户端连接

通过创建 WindowsAzure.MobileServiceClient 对象来创建客户端连接。 将 appUrl 替换为移动应用的 URL。

var client = WindowsAzure.MobileServiceClient(appUrl);

使用表

若要访问或更新数据,请创建对后端表的引用。 将 tableName 替换为表的名称

var table = client.getTable(tableName);

获得表引用后,可以进一步处理表:

查询表引用

有了表引用后,可以使用它来查询服务器上的数据。 查询采用类似于 LINQ 的语言进行。 若要从表返回所有数据,请使用以下代码:

/**
 * Process the results that are received by a call to table.read()
 *
 * @param {Object} results the results as a pseudo-array
 * @param {int} results.length the length of the results array
 * @param {Object} results[] the individual results
 */
function success(results) {
   var numItemsRead = results.length;

   for (var i = 0 ; i < results.length ; i++) {
       var row = results[i];
       // Each row is an object - the properties are the columns
   }
}

function failure(error) {
    throw new Error('Error loading data: ', error);
}

table
    .read()
    .then(success, failure);

使用结果调用成功函数。 请勿在成功函数中使用 for (var i in results),因为当使用其他查询函数(如 .includeTotalCount())时,它将循环访问结果中包含的信息。

有关查询语法的详细信息,请参阅 Query 对象文档

筛选服务器上的数据

可以在表引用上使用 where 子句:

table
    .where({ userId: user.userId, complete: false })
    .read()
    .then(success, failure);

还可以使用筛选对象的函数。 在这种情况下,将 this 变量分配给正在筛选的当前对象。 以下代码在功能上等效于前面的示例:

function filterByUserId(currentUserId) {
    return this.userId === currentUserId && this.complete === false;
}

table
    .where(filterByUserId, user.userId)
    .read()
    .then(success, failure);

分页浏览数据

利用 take()skip() 方法。 例如,如果要将表拆分为 100 行记录:

var totalCount = 0, pages = 0;

// Step 1 - get the total number of records
table.includeTotalCount().take(0).read(function (results) {
    totalCount = results.totalCount;
    pages = Math.floor(totalCount/100) + 1;
    loadPage(0);
}, failure);

function loadPage(pageNum) {
    let skip = pageNum * 100;
    table.skip(skip).take(100).read(function (results) {
        for (var i = 0 ; i < results.length ; i++) {
            var row = results[i];
            // Process each row
        }
    }
}

.includeTotalCount() 方法用于向结果对象添加 totalCount 字段。 totalCount 字段填充了不使用分页时将返回的记录总数。

然后,可以使用页面变量和某些 UI 按钮来提供页面列表;使用 loadPage() 加载每个页面的新记录。 实现缓存以加快对已加载的记录的访问速度。

返回已排序的数据

使用 .orderBy().orderByDescending() 查询方法:

table
    .orderBy('name')
    .read()
    .then(success, failure);

有关 Query 对象的详细信息,请参阅 [查询对象文档]。

插入数据

使用适当的日期创建 JavaScript 对象,并异步调用 table.insert()

var newItem = {
    name: 'My Name',
    signupDate: new Date()
};

table
    .insert(newItem)
    .done(function (insertedItem) {
        var id = insertedItem.id;
    }, failure);

成功插入后,将返回插入的项,其中包含同步操作所需的额外字段。 使用此信息更新自己的缓存,以便以后进行更新。

Azure 移动应用 Node.js 服务器 SDK 支持用于开发的动态架构。 动态架构允许通过在插入或更新操作中指定列来向表添加列。 建议在将应用程序移动到生产环境之前关闭动态架构。

修改数据

.insert() 方法类似,应创建 Update 对象,然后调用 .update()。 update 对象必须包含要更新的记录的 ID - 读取记录或调用 .insert()时获取 ID。

var updateItem = {
    id: '7163bc7a-70b2-4dde-98e9-8818969611bd',
    name: 'My New Name'
};

table
    .update(updateItem)
    .done(function (updatedItem) {
        // You can now update your cached copy
    }, failure);

删除数据

若要删除记录,请调用 .del() 方法。 在对象引用中传递 ID:

table
    .del({ id: '7163bc7a-70b2-4dde-98e9-8818969611bd' })
    .done(function () {
        // Record is now deleted - update your cache
    }, failure);

对用户进行身份验证

Azure 应用服务支持使用各种外部标识提供者对应用用户进行身份验证和授权:Facebook、Google、Microsoft 帐户和 Twitter。 可以设置对表的权限,以将特定操作的访问限制为仅经过身份验证的用户。 还可以使用经过身份验证的用户的标识在服务器脚本中实现授权规则。 有关详细信息,请参阅 身份验证入门 教程。

在 Apache Cordova 应用中使用身份验证时,必须提供以下 Cordova 插件:

注意

iOS 和 Android 中最近的安全更改可能会使服务器流身份验证不可用。 在这些情况下,必须使用客户端流。

支持两个身份验证流:服务器流和客户端流。 服务器流提供最简单的身份验证体验,因为它依赖于提供程序的 Web 身份验证接口。 客户端流允许更深入地与特定于设备的功能(例如单一登录)集成,因为它依赖于特定于提供程序的设备 SDK。

使用提供程序进行身份验证 (服务器流)

若要让移动应用管理应用中的身份验证过程,必须将应用注册到标识提供者。 然后在 Azure 应用服务中,需要配置提供程序提供的应用程序 ID 和机密。 有关详细信息,请参阅本教程 向应用添加身份验证

注册标识提供者后,请使用提供程序的名称调用 .login() 方法。 例如,若要使用 Facebook 登录,请使用以下代码:

client.login("facebook").done(function (results) {
     alert("You are now signed in as: " + results.userId);
}, function (err) {
     alert("Error: " + err);
});

提供程序的有效值为“aad”、“facebook”、“google”、“microsoftaccount”和“twitter”。

注意

由于安全问题,某些身份验证提供程序可能无法使用服务器流。 在这些情况下,必须使用客户端流方法。

在这种情况下,Azure 应用服务管理 OAuth 2.0 身份验证流。 它显示所选提供程序的登录页,并在与标识提供者成功登录后生成应用服务身份验证令牌。 登录函数完成后返回一个 JSON 对象,该对象分别在 userId 和 authenticationToken 字段中公开用户 ID 和应用服务身份验证令牌。 此令牌可以缓存并重复使用,直到它过期。

使用提供程序进行身份验证(客户端流)

应用还可以独立联系标识提供者,然后将返回的令牌提供给应用服务进行身份验证。 通过此客户端流,可以为用户提供单一登录体验,或从标识提供者检索额外的用户数据。

社交身份验证基本示例

此示例使用 Facebook 客户端 SDK 进行身份验证:

client.login("facebook", {"access_token": token})
.done(function (results) {
     alert("You are now signed in as: " + results.userId);
}, function (err) {
     alert("Error: " + err);
});

此示例假定相应的提供程序 SDK 提供的令牌存储在令牌变量中。 每个提供程序所需的详细信息略有不同。 请参阅 Azure 应用服务身份验证和授权文档 来确定有效负载的确切形式。

获取有关经过身份验证的用户的信息

可以使用具有任何 HTTP/REST 库的 HTTP 调用从 /.auth/me 终结点检索身份验证信息。 确保将 X-ZUMO-AUTH 标头设置为身份验证令牌。 身份验证令牌存储在 client.currentUser.mobileServiceAuthenticationToken中。 例如,若要使用提取 API:

var url = client.applicationUrl + '/.auth/me';
var headers = new Headers();
headers.append('X-ZUMO-AUTH', client.currentUser.mobileServiceAuthenticationToken);
fetch(url, { headers: headers })
    .then(function (data) {
        return data.json()
    }).then(function (user) {
        // The user object contains the claims for the authenticated user
    });

提取 npm 包 或从 CDNJS下载浏览器。 数据作为 JSON 对象接收。

为外部重定向 URL 配置移动应用服务。

几种类型的 Apache Cordova 应用程序使用环回功能来处理 OAuth UI 流。 localhost 上的 OAuth UI 流会导致问题,因为身份验证服务默认仅知道如何利用服务。 有问题的 OAuth UI 流的示例包括:

  • 波纹仿真器。
  • 使用 Ionic 实时重载。
  • 在本地运行移动后端
  • 在提供身份验证的不同 Azure 应用服务中运行移动后端。

按照以下说明将本地设置添加到配置:

  1. 登录到 Azure 门户

  2. 选择 所有资源应用服务 然后单击移动应用的名称。

  3. 单击“工具”

  4. 在“观察”菜单中单击 资源资源管理器,然后单击 “转到”。 此时会打开一个新窗口或选项卡。

  5. 展开左侧导航中站点的 配置身份验证 节点。

  6. 单击“编辑

  7. 查找“allowedExternalRedirectUrls”元素。 它可以设置为 null 或值数组。 将值更改为以下值:

    "allowedExternalRedirectUrls": [
        "http://localhost:3000",
        "https://localhost:3000"
    ],
    

    将 URL 替换为服务的 URL。 示例包括 http://localhost:3000(对于 Node.js 示例服务),或 http://localhost:4400(对于波纹服务)。 但是,这些 URL 是示例 - 你的情况(包括示例中提到的服务)可能有所不同。

  8. 单击屏幕右上角的 读/写 按钮。

  9. 单击绿色 PUT 按钮。

此时将保存设置。 在设置完成保存之前,请勿关闭浏览器窗口。 此外,将这些环回 URL 添加到应用服务的 CORS 设置:

  1. 登录到 Azure 门户
  2. 选择 所有资源应用服务 然后单击移动应用的名称。
  3. “设置”边栏选项卡会自动打开。 如果没有,请单击 “所有设置”
  4. 在 API 菜单下单击 CORS
  5. 输入要添加到提供的框中的 URL,然后按 Enter。
  6. 根据需要输入更多 URL。
  7. 单击“保存 保存设置。

新设置生效大约需要 10-15 秒。