【问题标题】:Azure Mobile App Offline Sync - different usersAzure 移动应用离线同步 - 不同的用户
【发布时间】:2017-07-19 04:20:14
【问题描述】:

现状

我创建了一个使用 Azure SDK 进行离线数据同步的应用。同步工作正常,包括通过 Microsoft 帐户进行用户身份验证。在 Azure 中,我目前使用的是 Easy Tables。

问题

现在,当我使用两个不同的用户从两个不同的测试设备登录时,我可以看到相同的数据。我的期望是经过身份验证的用户只能看到使用他自己的用户 ID 添加/更新的内容。

实际问题

是否所有经过身份验证的用户都可以查看所有其他用户的数据?那么我是否必须在获取数据时添加一些带有用户 ID 的列(基于 Microsoft 帐户 ID)并在 where 子句中添加条件? (这很奇怪,因为所有数据都会同步给所有用户)

我正在查看文档,但找不到正确的信息。我还没有为这个问题添加任何代码,因为我不清楚这是否是设计使然,这是否是客户端的东西,或者服务器端的配置是否需要为此进行调整。

【问题讨论】:

  • 您解决了这个问题吗,需要进一步的帮助吗?

标签: c# azure azure-mobile-services


【解决方案1】:

同步工作正常,包括通过 Microsoft 帐户进行用户身份验证。在 Azure 中,我目前使用的是 Easy Tables。

Easy Tables 与 Node.js 后端一起使用,当通过 Easy Tables 添加表时,它将帮助您自动为添加的表构建 node.js 后端。您可以在 azure 门户上的移动应用下利用“开发工具 > 应用服务编辑器(预览版)”来检查您的后端。

是否所有经过身份验证的用户都可以查看所有其他用户的数据?那么我是否必须在获取数据时添加一些带有用户 ID(基于 Microsoft 帐户 ID)的列并在 where 子句中添加条件?

对于移动客户端,您可以使用 Azure Mobile Client SDK 连接您的 azure 移动应用。假设您利用 Server-managed authentication 并使用以下代码使用 Microsoft 帐户进行日志记录:

MobileServiceUser user=wait MobileServiceClient.LoginAsync(MobileServiceAuthenticationProvider.MicrosoftAccount);

您可以通过MobileServiceClient.CurrentUser 检索记录的用户信息,CurrentUser 具有属性UserId。由于您使用的是 Easy Table,因此您只需通过 Azure 门户将 UserId 列添加到每个与用户相关的表中。此外,您需要在移动客户端应用程序中更改相关的 SQLite 表。

对于离线同步,您可以如下定义 OData 查询,以从远程表中检索属于指定用户的项目。

await todoTable.PullAsync("incsync_ToDoTable_CurrentUser", todoTable.CreateQuery().Where(t => t.UserId=="<userId>");

更多详情,我推荐你参考adrian hall的书Data Access and Offline Sync。

更新:

问题:

1) 在后端评估的过滤条件并且仅同步具有给定 userId 的行,您可以在处理 pull 操作时利用 Fiddler 捕获网络跟踪。

2) 为了获得更安全的方法,您可以在将发送到表控制器的数据存储在服务器端之前对其进行调整,而不是在移动客户端上指定userId。对于 node.js 后端,您可以在插入数据之前按如下方式修改代码:

table.insert(function (context) {
  context.item.userId = context.user.id;
  return context.execute();
});

更多详情可以参考30 DAYS OF ZUMO.V2 (AZURE MOBILE APPS): DAY 6 – PERSONAL TABLES。

此外,对于 C# 后端,您可以按如下方式检索 UserId:

public string UserId
{
    get
    {
        var principal = this.User as ClaimsPrincipal;
        return principal.FindFirst(ClaimTypes.NameIdentifier).Value;
    }
}

并修改添加新项目的操作,如下所示:

// POST tables/TodoItem
public async Task<IHttpActionResult> PostTodoItem(TodoItem item)
{
    item.UserId = UserId;
    TodoItem current = await InsertAsync(item);
    return CreatedAtRoute("Tables", new { id = current.Id }, current);
}

更多详情可以参考Per-User Data。

【讨论】:

  • 感谢您的更新。正如你所说,我正在使用LoginAsync。两个问题:1) 使用Where(t =&gt; t.UserId == "&lt;userId&gt;");时,过滤器应用在哪里?换句话说,是否所有数据都同步到本地数据库,然后使用该谓词进行过滤?还是在后端评估过滤条件并且仅同步具有给定 userId 的行? 2) 这种方法实际上意味着我必须将用户 ID 添加到我的对象模型的每个实例中,对吗?因此,假设每个 TodoItem 都会在创建后立即获得一个 UserId。有没有办法让 SDK 处理这个字段?
  • 我已经更新了我的回答来解释你关心的问题,你可以参考一下。
【解决方案2】:

要过滤每个用户的条目,您必须在表中添加一个 UserId 列,其中包含拥有该项目的用户的 ID。

然后,您可以在客户端应用程序中过滤您的表格以仅接收当前用户的项目。

或者甚至更好地在服务器端应用过滤器,这样您的客户端应用程序只接收当前登录用户的项目。

但我不确定这是否可以通过简单的表实现,您可能必须在此 repo 的“后端”部分中实现“完整”服务器版本:https://github.com/Azure/azure-mobile-apps-quickstarts

【讨论】:

    猜你喜欢
    • 2023-01-07
    • 1970-01-01
    • 1970-01-01
    • 2017-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多