2

我已经阅读了很多关于 Sync Adapter 的教程,例如http://www.c99.org/2010/01/23/writing-an-android-sync-provider-part-1上的教程以及 SampleSyncAdapter 示例Android 开发者网站上的代码。但我不明白服务器端如何处理身份验证和同步查询。我可以使用 php 从 mySQL 服务器数据库进行查询吗?

4

1 回答 1

15

您缺少的部分不是同步适配器的一部分。这是AbstractAccountAuthenticator. 它是实际处理用户密码并将其传递给服务器的类,它需要以与相关服务器完美匹配的方式编写。

如何:

首先,这个过程是如何工作的?

  1. 用户在 Settings->Accounts and Sync 页面上输入用户名和密码。
  2. (稍后...)同步过程开始。
  3. SyncAdapter 调用blockingGetAuthToken()
  4. AccountAuthenticator 启动。
  5. AccountAuthenticator 使用常规的 http(或理想情况下为 https)身份验证连接到服务器,一旦通过身份验证,就会从服务器请求“令牌”。此令牌是一个大的(例如 128 位)随机数,只有在您使用基于密码的身份验证登录时才能从服务器获取。
  6. AccountAutenticator 缓存令牌,然后将令牌返回给 SyncAdapter。
  7. SyncAdapter 尝试访问服务器上的内容,并将令牌作为其请求中 http 标头的一部分传递。
  8. 服务器接受令牌代替正常的 http-auth,并允许服务请求。
  9. 未来的同步尝试最终会跳过这个过程的大部分。在接下来的同步尝试中,当 SyncAdapter 调用 blockingGetAuthToken() 时,AccountAuthenticator 只需返回缓存的令牌,无需重新进行身份验证。

所以这个令牌是有限使用的——一段时间后,服务器会拒绝接受它。此时,SyncAdapter 尝试使用令牌并收到身份验证错误。那么呢?

  1. SyncAdapter 调用 invalidateToken(token) 并将(现在已过期的令牌)传递回 AccountAuthenticator。
  2. AccountAuthenticator 在其缓存中找到令牌并将其丢弃。
  3. 在下一次调用blockingGetAuthToken() 时,AccountAuthenticator 将与服务器通信并获取新令牌。从那里,同步正常进行。

为什么?

所以有几个优点。

  1. 普通 http auth 通过 Internet 以明文形式传输密码。如果使用令牌,则只发送一次密码,多次发送令牌。这在一定程度上减少了密码对嗅探的暴露。
  2. https 身份验证避免了明文问题,但在移动连接方面可能很昂贵。使用令牌可以为实际携带数据的服务器调用提供更轻量级的 http 连接,只有在获得令牌时,才会在第一个请求上看到 https 开销。
  3. 隔离——AccountAuthenticator 知道用户的实际密码。SyncAdapter 只能访问令牌并且永远不会学习密码。这对谷歌来说很重要,因为它允许第三方应用程序使用 gmail 帐户和密码进行身份验证,而无需第三方应用程序(可能是恶意的)获取密码(并将其转发给狡猾的 naer-do -出色地)

有效期:

代币有点危险。任何可以访问令牌的人都可以以您的身份登录。因此,这里的良好做法:

  1. 服务器应在固定时间段后使用户的令牌过期。更多的偏执——更短的超时。
  2. 每当用户更改密码时,服务器都应使用户的所有令牌过期。
  3. 如果 Web 界面上的用户注销,服务器可能不会使分配给 Web 设备的令牌过期。令牌并没有真正的“注销”概念。
  4. 服务器应考虑将令牌绑定到首先请求它的 IP 地址,然后如果不同的 IP 地址随后尝试使用该令牌,则拒绝身份验证(但不一定过期)该令牌。如果您这样做,服务器肯定需要能够为每个用户创建多个令牌(每个用户一个令牌:ipaddress 组合)——考虑一个有两个移动设备的用户——否则,每次同步时,它都会失效对方的令牌。还要考虑一下,两台设备都在家庭wifi上(在路由器后面共享一个IP地址,然后一台设备离开并开始使用移动网络——这就是你可能选择不过期的原因,所以仍然坐在家里的设备可以继续使用令牌。但是,漫游的一个设备将看到身份验证失败并建立自己的新令牌。
  5. 根据您的偏执程度,请考虑仅通过 https 接受身份验证令牌。Firesheep是一个很好的例子,说明了被盗的 Auth Token 可以获得什么。如果您有用户敏感数据,则应仅通过 https 接受。此外,即使您没有用户敏感数据,您也可以考虑编写一个协议,该协议要求 https 更改数据库,同时允许 http 读取。
于 2012-01-01T02:34:30.430 回答