Android SyncAdapter 服务器端实现

发布于 2024-12-20 18:49:26 字数 302 浏览 4 评论 0原文

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

I have read a lot of tutorials on Sync Adapter such as the tutorial on http://www.c99.org/2010/01/23/writing-an-android-sync-provider-part-1 as well as the SampleSyncAdapter sample code on Android Developer website.
But I don't understand that how the server side handles the Authentication and synchronization queries. Is it possible for me to use php to query from a mySQL server database?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一腔孤↑勇 2024-12-27 18:49:26

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

如何:

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

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

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

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

为什么?

所以有几个优点。

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

过期:

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

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

The piece you're missing is not part of a Sync Adapter. It's the AbstractAccountAuthenticator. It's the class that actually deals with the user's password, and passing it to the server, and it will need to be written in a manner that's well paired with the server in question.

How:

First off, how does the process work?

  1. User enters username and password on the Settings->Accounts and Sync page.
  2. (Later...) Sync process starts.
  3. SyncAdapter calls blockingGetAuthToken()
  4. AccountAuthenticator starts.
  5. AccountAuthenticator uses regular http (or ideally, https) authentication to connect to the server, and once authenticated, requests a 'token' from the sever. This token is a large (say, 128 bit) random number, should only be able to be obtained from the server if you've logged in using password based authentication.
  6. AccountAutenticator caches the token, and then returns the token to the SyncAdapter.
  7. SyncAdapter tries to access content on the server, and passes the token as part of the http headers in its requests.
  8. Server accepts the token in lieu of normal http-auth, and allows the request to be served.
  9. Future sync attempts will end up skipping much of this process. On the following sync attempts, when the SyncAdapter calls blockingGetAuthToken(), the AccountAuthenticator simply returns the cached token, not needing to re-authenticate.

So this token is limited use -- After a while, the server will refuse to accept it. At that point, the SyncAdapter tries to use the token and gets an authentication error. So then what?

  1. The SyncAdapter calls invalidateToken(token) and passes the (now expired token) back to the AccountAuthenticator.
  2. AccountAuthenticator finds the token in its cache and throws it away.
  3. On the next call to blockingGetAuthToken(), the AccountAuthenticator will go communicate with the server and get a new token. From there, sync proceeds normally.

Why?

So there are several advantages.

  1. Normal http auth transmits the password in plaintext over the internet. If tokens are used, the password is sent only once, the token many times. This somewhat reduces the exposire of the password to sniffing.
  2. https authentication avoids the plaintext problem, but can be expensive, in terms of a mobile connection. Use of tokens allows lighter-weight http connections for the server calls that actually carry data, the https overhead is only seen on the first request, when the token is obtained.
  3. Segregation -- An AccountAuthenticator knows the user's actual pasword. The SyncAdapter only gets access to the the token and never learns the password. This is important to, say Google, because it allows a third party app to use a gmail account and pasword to authenticate, without the third party app (which could be malicious) to get the pasword (and forward it to a devious naer-do-well)

Expiration:

Tokens are kind of dangerous. Anyone who gets access to the token can login as you. So, good practices here:

  1. The server should expire a user's tokens after a fixed period of time. More paranoia -- shorter timeouts.
  2. The server should expire all a user's tokens whenever the user changes their password.
  3. The server should probably not expire a token assigned to a web device if the user on
    a web interface logs out. There isn't really a 'logout' concept for tokens.
  4. The server should consider tying a token to the IP address that first requests it, and then refuse authentication (but not necessarily expire) the token if a different IP address subsequently tries to use that token. If you do this, the server will definitely need to be capable of creating multiple tokens per user (one token per user:ipaddress combination) -- consider a user with two mobile devices -- without that, each time one syncs, it would invalidate the other's token. Consider also, two devices both on home wifi (sharing one ip address behind a router, and then one device leaves and starts using mobile network -- That's why you might choose not to expire, so the device still sitting at home can continue to use the token. However, the one device that goes roaming will see an auth failure and establish its own new token. When it comes home, the server should be sure to provide the same token that's already established for that IP address.)
  5. Depending on your paranoia level, consider only accepting auth tokens over https anyway. Firesheep is a great example of what a stolen Auth Token can get you. If you have user-sensitive data, you should only accept over https. Also, even if you don't have user-sensitive data, you might consider writing a protocol that demands https to change the DB while allowing http to read.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文