You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取D9注册提交的明文密码以同步用户至D7站点

方案1:拦截注册表单获取明文密码同步到D7

Drupal 9的hook_user_presave/hook_user_insert中拿到的密码已完成加密,因此需要在密码加密前拦截注册表单的提交数据:

  • 通过hook_form_alter修改用户注册表单,将自定义提交回调放在Drupal默认逻辑之前
  • 在自定义回调中提取明文密码,调用D7的API完成用户同步
  • 保留表单默认逻辑,完成D9侧的用户创建流程

示例代码:

/**
 * Implements hook_form_alter().
 */
function mymodule_form_user_register_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
  // 将自定义回调插入到默认提交队列的最前面
  array_unshift($form['actions']['submit']['#submit'], 'mymodule_user_register_submit');
}

/**
 * 自定义注册表单提交回调,获取明文密码并同步至D7
 */
function mymodule_user_register_submit(array &$form, \Drupal\Core\Form\FormStateInterface $form_state) {
  // 提取表单中的明文密码及用户信息
  $plain_password = $form_state->getValue('pass');
  $username = $form_state->getValue('name');
  $email = $form_state->getValue('mail');

  // 调用D7用户注册API(替换为你的实际API地址和验证方式)
  $d7_api_url = 'https://your-d7-site.com/api/user/register';
  $sync_data = [
    'name' => $username,
    'mail' => $email,
    'pass' => $plain_password,
    // 添加其他需要同步的用户字段
  ];

  $http_client = \Drupal::httpClient();
  try {
    $response = $http_client->post($d7_api_url, [
      'json' => $sync_data,
      'headers' => ['Authorization' => 'Bearer YOUR_D7_API_TOKEN'],
    ]);
    \Drupal::logger('mymodule')->info('用户同步至D7成功:@username', ['@username' => $username]);
  }
  catch (\Exception $e) {
    \Drupal::logger('mymodule')->error('用户同步至D7失败:@message', ['@message' => $e->getMessage()]);
    // 可选:同步失败时阻止D9创建用户,或标记用户后续重试
    // $form_state->setErrorByName('', '同步至遗留站点失败,请稍后重试');
  }
}
方案2:迁移D9加密密码到D7(兼容处理)

若不想处理明文密码,可让D7直接支持验证D9的密码哈希:

  1. 确认D7的密码哈希兼容性:

    • Drupal 7从7.38版本开始,核心原生支持bcrypt哈希(需PHP >= 5.5.0)
    • 若D7版本低于7.38,安装password_compat模块,为PHP 5.3+提供bcrypt支持
  2. 直接迁移密码哈希:

    • 将D9用户表users_field_data中的pass字段值(bcrypt格式哈希,以$2y$开头)直接复制到D7的users表pass字段
    • D7会自动识别bcrypt格式的哈希,使用对应逻辑处理登录验证
  3. 批量迁移示例:
    可编写Drush命令或自定义脚本批量同步,伪代码如下:

// 批量同步D9用户哈希密码到D7
$d9_users = \Drupal::entityTypeManager()->getStorage('user')->loadMultiple();
$http_client = \Drupal::httpClient();
$d7_api_token = 'YOUR_D7_API_TOKEN';

foreach ($d9_users as $user) {
  if ($user->id() == 1) continue; // 跳过管理员用户
  $sync_data = [
    'uid' => $user->id(), // 可选:保持UID一致
    'name' => $user->getAccountName(),
    'mail' => $user->getEmail(),
    'pass' => $user->getPassword(), // D9的加密哈希值
  ];

  try {
    $response = $http_client->post('https://your-d7-site.com/api/user/update', [
      'json' => $sync_data,
      'headers' => ['Authorization' => "Bearer $d7_api_token"],
    ]);
    \Drupal::logger('mymodule')->info('用户密码哈希同步成功:@username', ['@username' => $user->getAccountName()]);
  }
  catch (\Exception $e) {
    \Drupal::logger('mymodule')->error('用户密码哈希同步失败:@message', ['@message' => $e->getMessage()]);
  }
}
注意事项
  • 调用D7 API时必须使用HTTPS,同时做好接口权限控制(如OAuth2或API令牌验证)
  • 方案1中若API同步失败,建议使用队列模块实现异步重试,避免阻塞用户注册流程
  • 方案2中若D7无法识别bcrypt哈希,检查PHP版本及D7核心/模块版本,确保bcrypt支持已启用

内容的提问来源于stack exchange,提问作者HigherLogic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 06:42:58