The other way of solving it is to have the server sign whatever data is sent to the client via an HMAC. That combined with some basic serialization gets you a generic approach that you can use for all kinds of things. This also has the scalable benefit that it doesn't require a centralize persistent store.
Here's a high level summary of how we handle these use cases:
# Server -> Client (Assume server wants to round trip object X)
1. Server serializes X to a URL friendly string (JSON + Base64 works well enough for this)
2. Server calls generateToken(type, message, expiration) which signs the message/expiration with secretKey+type. It then returns a JSON/Base64 serialized map containing message/expiration/hmac.
# Client -> Server 1. Client sends back the final JSON/Base64 string
2. Server decodes and extracts the message, expiration, and hmac
3. Server verifies the HMAC by regenerating it and comparing it against the client supplied one
4. Server verifies the expiration date hasn't passed
5. Server returns back the deserialized object
Couple of notes:* The HMAC prevents the client from tampering with the message
* The 'type' field is so that tokens generated for one request type cannot be accepted somewhere else in the application. It's kind of like namespacing.
* The 'type' field does not need to be included in the message itself. It's inferred by the server based on the client request type.
* The object/message itself can be blank. In that case this becomes a secure expiring token.
Couple of possible extensions/improvements:
* If the data being sent back/forth is particularly sensitive you could also have the server encrypt either it or the entire message itself. If it's not though then it would be overkill.
* Including the requesting clients IP in the HMAC generation to further limit the set of user's it would validate against is an option as well though generally that's a bad idea. People's IP addresses change fairly often and that kills the basic use case of taking your work home with you.