我已经阅读了很多关于 Sync Adapter 的教程,例如http://www.c99.org/2010/01/23/writing-an-android-sync-provider-part-1上的教程以及 SampleSyncAdapter 示例Android 开发者网站上的代码。但我不明白服务器端如何处理身份验证和同步查询。我可以使用 php 从 mySQL 服务器数据库进行查询吗?
问问题
4816 次
1 回答
15
您缺少的部分不是同步适配器的一部分。这是AbstractAccountAuthenticator
. 它是实际处理用户密码并将其传递给服务器的类,它需要以与相关服务器完美匹配的方式编写。
如何:
首先,这个过程是如何工作的?
- 用户在 Settings->Accounts and Sync 页面上输入用户名和密码。
- (稍后...)同步过程开始。
- SyncAdapter 调用blockingGetAuthToken()
- AccountAuthenticator 启动。
- AccountAuthenticator 使用常规的 http(或理想情况下为 https)身份验证连接到服务器,一旦通过身份验证,就会从服务器请求“令牌”。此令牌是一个大的(例如 128 位)随机数,只有在您使用基于密码的身份验证登录时才能从服务器获取。
- AccountAutenticator 缓存令牌,然后将令牌返回给 SyncAdapter。
- SyncAdapter 尝试访问服务器上的内容,并将令牌作为其请求中 http 标头的一部分传递。
- 服务器接受令牌代替正常的 http-auth,并允许服务请求。
- 未来的同步尝试最终会跳过这个过程的大部分。在接下来的同步尝试中,当 SyncAdapter 调用 blockingGetAuthToken() 时,AccountAuthenticator 只需返回缓存的令牌,无需重新进行身份验证。
所以这个令牌是有限使用的——一段时间后,服务器会拒绝接受它。此时,SyncAdapter 尝试使用令牌并收到身份验证错误。那么呢?
- SyncAdapter 调用 invalidateToken(token) 并将(现在已过期的令牌)传递回 AccountAuthenticator。
- AccountAuthenticator 在其缓存中找到令牌并将其丢弃。
- 在下一次调用blockingGetAuthToken() 时,AccountAuthenticator 将与服务器通信并获取新令牌。从那里,同步正常进行。
为什么?
所以有几个优点。
- 普通 http auth 通过 Internet 以明文形式传输密码。如果使用令牌,则只发送一次密码,多次发送令牌。这在一定程度上减少了密码对嗅探的暴露。
- https 身份验证避免了明文问题,但在移动连接方面可能很昂贵。使用令牌可以为实际携带数据的服务器调用提供更轻量级的 http 连接,只有在获得令牌时,才会在第一个请求上看到 https 开销。
- 隔离——AccountAuthenticator 知道用户的实际密码。SyncAdapter 只能访问令牌并且永远不会学习密码。这对谷歌来说很重要,因为它允许第三方应用程序使用 gmail 帐户和密码进行身份验证,而无需第三方应用程序(可能是恶意的)获取密码(并将其转发给狡猾的 naer-do -出色地)
有效期:
代币有点危险。任何可以访问令牌的人都可以以您的身份登录。因此,这里的良好做法:
- 服务器应在固定时间段后使用户的令牌过期。更多的偏执——更短的超时。
- 每当用户更改密码时,服务器都应使用户的所有令牌过期。
- 如果 Web 界面上的用户注销,服务器可能不会使分配给 Web 设备的令牌过期。令牌并没有真正的“注销”概念。
- 服务器应考虑将令牌绑定到首先请求它的 IP 地址,然后如果不同的 IP 地址随后尝试使用该令牌,则拒绝身份验证(但不一定过期)该令牌。如果您这样做,服务器肯定需要能够为每个用户创建多个令牌(每个用户一个令牌:ipaddress 组合)——考虑一个有两个移动设备的用户——否则,每次同步时,它都会失效对方的令牌。还要考虑一下,两台设备都在家庭wifi上(在路由器后面共享一个IP地址,然后一台设备离开并开始使用移动网络——这就是你可能选择不过期的原因,所以仍然坐在家里的设备可以继续使用令牌。但是,漫游的一个设备将看到身份验证失败并建立自己的新令牌。
- 根据您的偏执程度,请考虑仅通过 https 接受身份验证令牌。Firesheep是一个很好的例子,说明了被盗的 Auth Token 可以获得什么。如果您有用户敏感数据,则应仅通过 https 接受。此外,即使您没有用户敏感数据,您也可以考虑编写一个协议,该协议要求 https 更改数据库,同时允许 http 读取。
于 2012-01-01T02:34:30.430 回答