hook_tokens_alter() not applying to [user:one-time-login-url] Token I'm trying to alter the one time login token. I am implementing hook_tokens_alter to do this.

/**
 * Implements hook_tokens_alter
 * @param $replacements
 * @param $context
 */
function portalapi_tokens_alter(&amp;$replacements,  $context){
  if(isset($context['data']['user'])){
    foreach($context['tokens'] as $name =&gt; $original){
      switch ($name) {
        case 'one-time-login-url':
          $timestamp = REQUEST_TIME;
          $token = user_pass_rehash($context['data']['user']-&gt;pass, $timestamp, $context['data']['user']-&gt;login, $context['data']['user']-&gt;uid);
          $resetpath = url(variable_get('portal_frontend_url').'/reset-password/'.$token.'-'.$timestamp);
          $replacements[$original] = $resetpath;
          break;
      }
    }
  }
}


Logging the $replacements array at the end of the function call shows the expected changes. However, the token output isn't altered when used (for example when sending password reset emails).

As a quick background here - We're implementing an entirely headless front end serviced by an API, we need to use a different domain in the one time login link and a different structure.

What am i missing?
You cannot alter it because that token is not returned from user_tokens(). You get that token only with code similar to the following one.

$text_with_tokens_replaced = token_replace($text, $variables, array('language' =&gt; $language, 'callback' =&gt; 'user_mail_tokens', 'sanitize' =&gt; FALSE, 'clear' =&gt; TRUE));


The problem is that first the implementations of hook_tokens_alter() are called, then the callback passed to token_replace() is called. The effect is that every value you set for that token is then changed from the callback.

This is the code used from token_replace().

  $replacements = array();
  foreach ($text_tokens as $type =&gt; $tokens) {
    $replacements += token_generate($type, $tokens, $data, $options);
    if (!empty($options['clear'])) {
      $replacements += array_fill_keys($tokens, '');
    }
  }

  // Optionally alter the list of replacement values.
  if (!empty($options['callback']) &amp;&amp; function_exists($options['callback'])) {
    $function = $options['callback'];
    $function($replacements, $data, $options);
  }


token_generate() is the function invoking the token hooks (including the alter hooks).

  $replacements = module_invoke_all('tokens', $type, $tokens, $data, $options);

  // Allow other modules to alter the replacements.
  $context = array(
    'type' =&gt; $type,
    'tokens' =&gt; $tokens,
    'data' =&gt; $data,
    'options' =&gt; $options,
  );
  drupal_alter('tokens', $replacements, $context);