【反馈】一个关于站点登录相关的问题(不确定是不是bug)-zibll综合交流社区-zibll子比主题-zibll子比社区

【反馈】一个关于站点登录相关的问题(不确定是不是bug)

一、情况是这样

站里同时开了两个功能:

  • 强制绑定邮箱
  • 谷歌登录

本来是想让用户注册更省事,结果反而多了一道坎。

二、用户的反馈

最近有几个人来问:明明点的是谷歌登录、授权页也走完了,为什么还要再填一遍邮箱?

他们觉得这一步很没必要 —— 谷歌那边邮箱都给了,还要自己再打一遍,感觉跟白登录一样。也有一位用户说因为这个干脆就没注册下去。

我自己也试了一下,确实是这个流程,不太好意思让用户重复做这件事。

三、我排查了一下,问题大概出在这里

谷歌授权成功、邮箱也返回回来了,但主题在自动创建新用户的时候,没有把谷歌的邮箱写进用户邮箱字段,所以新账号的邮箱是空的。

而「强制绑定」的判断逻辑只认「用户邮箱是否为空」这一条 —— 空着就跳绑定页。于是每次都要用户手动补一遍。

顺便提一句:谷歌那个取用户信息的接口,返回的字段名是 verified_email(不是 OIDC 里的 email_verified),如果后续要判断「邮箱是否已验证」,两个最好都看一下,不然容易漏。

四、临时的解决办法

我这边先不动主题本体,在子主题里挂了个钩子:在主题做「绑定判定」之前,把谷歌返回的、已验证的邮箱自动写进用户邮箱。因为强制绑定的判断比这个钩子晚一步执行,所以登录完就能直接停在原来的页面上,不会再被弹去绑定页。

// 子主题 functions.php
// 第三方登录自动写入「已验证」邮箱,避免被强制绑定邮箱反复拦截

add_action('wp_login', function ($user_login, $user) {
    if ($user instanceof WP_User) zibll_fill_oauth_email($user);
}, 20, 2);

add_action('template_redirect', function () {
    zibll_fill_oauth_email(wp_get_current_user());
}, 9); // 比主题的绑定判定(优先级 10)早一步

function zibll_fill_oauth_email($user)
{
    if (!$user instanceof WP_User || !$user->ID) return;
    if (!empty($user->user_email)) return;   // 已经有邮箱,绝不覆盖

    // 会给邮箱的平台,谷歌的字段是 verified_email
    $map = array('google' => 'verified_email', 'microsoft' => '', 'facebook' => '', 'apple' => '');

    foreach ($map as $type => $need_verify) {
        $info = zib_get_user_meta($user->ID, 'oauth_' . $type . '_getUserInfo', true);
        if (empty($info['email']) || !is_email($info['email'])) continue;

        // 只认「已验证」的邮箱
        if ($need_verify) {
            $v = isset($info[$need_verify]) ? $info[$need_verify]
               : (isset($info['email_verified']) ? $info['email_verified'] : false);
            if (!filter_var($v, FILTER_VALIDATE_BOOLEAN)) continue;
        }

        // 邮箱已经被别的账号用了,就不抢绑,让用户手动处理
        $owner = email_exists($info['email']);
        if ($owner && (int) $owner !== (int) $user->ID) continue;

        add_filter('send_email_change_email', '__return_false');
        wp_update_user(array('ID' => $user->ID, 'user_email' => $info['email']));
        remove_filter('send_email_change_email', '__return_false');
        break;
    }
}

五、有几点还是得注意

自动写邮箱这件事不能图省事,不然会出安全问题:

  1. 只认第三方标记为「已验证」的邮箱。不然别人拿一个没验证过的邮箱就能顶掉你的账号。
  2. 邮箱如果已经被站里其他账号占了,别自动抢绑 —— 宁可回落到手动绑定页,也不要自动合并账号。
  3. 用户已经有邮箱的,坚决不覆盖。

我本地搭了个环境把整条登录流程跑了一遍,上面这几种情况也都测了,目前是正常的。

六、最后

不确定这个算不算设计上有意为之,但从用户反馈来看确实挺影响注册体验的。老唐有空的话,能不能顺手在官方版本里处理掉这个小问题  就是在自动建号的时候把第三方返回的邮箱带上(其他地方顺带看一眼就行)。只是进行反馈~!

请登录后发表评论

    没有回复内容