The sum of what the client stores and what your server stores must be sufficient to recover the user-specific secret data (e.g. Facebook access token). What the client stores is, mostly, the user's password (the only permanent storage area on the client side is the user's brain, if we want to allow the user to use several distinct machines at will). If I understand correctly, you do not want your server to store the data "as is": in case your server is fully compromised, the user's secrets should still be safe (as much as is possible).
This points to password-based encryption. From the user's password is derived a symmetric key K which is used to symmetrically encrypt a bundle which contains the user's secrets, e.g. the Facebook account. Technically, this would look like this:
- When the user registers, he chooses his password P and sends it to your server.
- Your server generates a random salt value S and computes PBKDF2 over P and S, to produce 256 bits of output T. Let's call A the first 128 bits of T, and K the other 128-bit half.
- The first half (A) is stored in the server's database; this will be used to authenticate users.
- The second half (K) is not stored; this is the symmetric key for that user. User's secrets will be encrypted with K.
- When the user logs in, he sends his name and P to your server (over HTTPS). Your server retrieves the salt S for that user (as stored in its database) and recomputes T (using P and S with PBKDF2). If the first half of the recomputed T matches the stored A, then the user is authenticated and the second half of T is K. The server can then decrypt the stored bundle and access the Facebook access token.
With this setup, the server never stores (on its disk or in its database) the cleartext Facebook access token, but it can access it when the user logs in; it is up to the server to remember (in RAM) the Facebook access token as long as it needs it.
Note that when the user changes his password, this also changes K (the server must also generates a new salt S, but even if the server mistakenly did not, K would still be changed); thus, the server must decrypt the stored bundle with the old K and encrypt it again with the new K when the password is changed. This is not hard to integrate because password-change interfaces customarily ask for the old password and the new password, so at that point the server has both.
Also note that when the password is forgotten, the bundle is lost. There is no recovery for that case. If the user forgets his own password, then you will have to do some password reset, which is akin to a new registration; and a new Facebook access token will have to be obtained.
In all of the above, we see that your server still sees the user's password. If your server is fully compromised and hijacked, then the attacker will be able to observe users' passwords and users' Facebook access tokens for all users who log in while the attacker controls the server. Preventing that is much harder. Arguably, if your server presents a Web interface only, where all "intelligence" on the client side is Javascript sent by your server, then it is impossible to do better than what the scheme above does, in that situation.