Someone I know was working on a problem like this, and used something along the lines of the tokens solution that you described. What they did is to use a user's unique user ID value, pass it through crypt(), and then embed that into their form as the token. That value would then be checked with the user ID inside the database, and if the two matched any other checks could then be run.
i would add a random string to it, because if you know that it's the crypted user id you can still attack a user. of course then a corrupted website would only
work for one user at a time, so it's much safer than without tokens.