drupal_initialize_session() creates a random session_id() at the beginning of the request. For anonymous users, who don't have sessions by default, this means session_id() is random for every request, thus making drupal_get_token() *not* work across requests.
Therefore, it seems plausible that drupal_get_token() should provide an option to initialize a dummy session_id() for anonymous users.
This is related to #506500: Make drupal_get_token() work without a session (anonymous users), but is slightly different since it specifically *wants* to invoke a session instead of avoiding sessions altogether.
Comments
Comment #1
c4rl commentedI believe the attached patch achieves this merely by creating a $_SESSION variable, but do remark if there is a better way. :)
Comment #2
quicksketchI don't think that this approach is correct. The point of drupal_get_token() is to ensure a unique token per visitor, but in the situation of anonymous users they very well may be getting pages served up by a reverse proxy cache (Varnish, nginx) or CDN (Limelight, Akamai), in which case you can't depend drupal_get_token() at all because users are getting each other's pages all the time.
By design, Drupal 7 makes it so that anonymous pages should be able to be served to any anonymous user equally. If you're in a situation where anonymous users should be passing through CDNs, reverse-proxy caches, and Drupal's own page cache, you could easily set a $_SESSION variable before your call to drupal_get_token() to ensure a consistent token per user. Tying an automatic $_SESSION setting into drupal_get_token() just doesn't feel right. In the situation of a module like Flag (which also works with anonymous users), we just use our own function to make a generic token out of an md5() of other properties (such as the drupal_private_key and a content_id), which can be served up to all anonymous users equally to work with reverse-proxy caches.
Comment #3
c4rl commentedMakes sense. Having a general option like this as part of the core API risks misuse.