首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >WordPress 集成 GitCode OAuth 2.0 登录:从零打造第三方账号认证插件

WordPress 集成 GitCode OAuth 2.0 登录:从零打造第三方账号认证插件

作者头像
佛系豪豪吖
发布2026-06-22 20:57:55
发布2026-06-22 20:57:55
1140
举报

前言

你的 WordPress 博客只有原生注册登录,用户需要单独注册一个账号,流失率高、体验差。如果能用 GitCode 账号一键登录,注册门槛直接归零。

昨天我给自己的博客 blog.rmzdb.cloud 开发了一个 GitCode OAuth 2.0 登录插件,从设计 OAuth 流程到写 PHP 代码再到接入 AeroCore 主题,半天时间搞定。这篇文章把整个过程完整记录下来,涉及 OAuth 2.0 协议、WordPress 插件开发、前端 DOM 注入和 Token 生命周期管理,全程可复现。

为什么选 GitCode?

GitCode 是 CSDN 旗下的国内头部代码托管平台,开发者群体和我的博客受众高度重合。"用 GitCode 登录"比"用 Google 登录"对国内开发者友好得多,而且 OAuth 2.0 接口完全标准化,和 GitHub / Gitee 的对接模式一模一样。

另外,GitCode OAuth 的 Token 交换接口接受 client_secret 放在 POST body,和 GitHub 行为一致,比 Gitee 的 Basic Auth Header 方式更简洁。

OAuth 2.0 授权码流程

整个登录过程分为 4 步:

用户点击「GitCode登录」→ 跳转 GitCode 授权页 → 用户授权 → 回调博客 → 换 Token → 拉用户信息 → 匹配/创建 WP 账号 → 登录

第一步:构造授权请求

用户点击按钮后,WordPress 收到 ?action=gitcode_login 请求,插件构造授权 URL 并 302 跳转:

代码语言:javascript
复制
$params = [
    'client_id'     => 'your_client_id',
    'redirect_uri'  => home_url('/wp-login.php?action=gitcode_callback'),
    'response_type' => 'code',
    'scope'         => 'all_user',
    'state'         => wp_generate_password(32, false), // 防 CSRF
];

wp_redirect('https://gitcode.com/oauth/authorize?' . http_build_query($params));
exit;

关键细节:

  • response_type=code 指定使用授权码模式(Authorization Code Grant),这是唯一正确的选择
  • scope=all_user 请求用户基本信息权限
  • state 参数是随机 32 位字符串,先存到 WordPress transients(有效期 5 分钟),回调时强制校验,防止 CSRF 攻击

第二步:用授权码换 Access Token

代码语言:javascript
复制
// 校验 state
$state = $_GET['state'] ?? '';
if (empty($state) || !get_transient('gcol_state_' . $state)) {
    wp_die('State 校验失败,可能是 CSRF 攻击,请重新登录。');
}
delete_transient('gcol_state_' . $state);

// 用 code 换 token
$url = 'https://gitcode.com/oauth/token?' . http_build_query([
    'grant_type' => 'authorization_code',
    'code'       => $code,
    'client_id'  => $client_id,
]);

$response = wp_remote_post($url, [
    'body'    => ['client_secret' => $client_secret],
    'timeout' => 15,
]);

注意 client_secret 放在 POST body 而不是 URL 参数里——这是 GitCode 的安全设计,和 GitHub 一致。

第三步:用 Access Token 获取用户信息

代码语言:javascript
复制
$response = wp_remote_get('https://api.gitcode.com/api/v5/user', [
    'headers' => ['Authorization' => 'Bearer ' . $access_token],
    'timeout' => 15,
]);

$gitcode_user = json_decode(wp_remote_retrieve_body($response), true);

拿到 idusernameemailnameavatar_url 等字段。

第四步:匹配或创建 WordPress 账号

这是整个插件最核心的逻辑——三策略用户匹配

代码语言:javascript
复制
// 策略1: 按 gitcode_id meta 精确匹配(已绑定过)
$users = get_users([
    'meta_key'   => 'gcol_gitcode_id',
    'meta_value' => $gitcode_user['id'],
    'number'     => 1,
]);

// 策略2: 按邮箱匹配(GitCode 邮箱 = WP 邮箱)
if ($gitcode_user['email']) {
    $user = get_user_by('email', $gitcode_user['email']);
}

// 策略3: 自动注册新账号
$user_id = wp_insert_user([
    'user_login'   => $username,
    'user_email'   => $email,
    'display_name' => $display_name,
    'user_pass'    => wp_generate_password(24),
    'role'         => $cfg['default_role'] ?: 'subscriber',
]);

三策略覆盖了所有场景:老用户回访(策略1)、已有 WP 账号绑 GitCode(策略2)、纯新用户(策略3),登录体验无缝衔接。

插件架构设计

整个插件 3 个 PHP 文件,职责分明:

代码语言:javascript
复制
plugins/gitcode-oauth-login/
├── gitcode-oauth-login.php   # 入口:单例 + 配置集中管理
├── includes/
│   ├── class-settings.php     # 后台设置页面
│   ├── class-oauth.php        # OAuth 核心流程 + 前端注入
│   └── class-profile.php      # 用户资料页绑定展示

入口:单例模式 + 配置集中管理

代码语言:javascript
复制
final class GCOL_Plugin
{
    private static $instance = null;

    public static function instance()
    {
        if (null === self::$instance) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    private function __construct()
    {
        GCOL_Settings::init();
        GCOL_OAuth::init();
        GCOL_Profile::init();
    }

    public static function config($key = null)
    {
        return [
            'client_id'     => get_option('gcol_client_id', ''),
            'client_secret' => get_option('gcol_client_secret', ''),
            'auto_register' => get_option('gcol_auto_register', '1'),
            'default_role'  => get_option('gcol_default_role', 'subscriber'),
        ];
    }
}

GCOL_Plugin::instance();

单例确保整个请求生命周期只有一个插件实例,不污染全局空间。配置通过 get_option 持久化到 wp_options 表。

设置页面:标准 WordPress Settings API

register_setting + add_settings_section + add_settings_field 构建后台设置页:

代码语言:javascript
复制
public static function field_callback()
{
    $url = home_url('/wp-login.php?action=gitcode_callback');
    echo '<input type="text" readonly value="' . esc_attr($url) . '" onclick="this.select()" />';
}

WordPress 登录页按钮

login_form 钩子往原生登录页注入 GitCode 按钮:

代码语言:javascript
复制
add_action('login_form', [__CLASS__, 'login_button']);

public static function login_button()
{
    $url = wp_login_url() . '?action=gitcode_login';
    echo '<div class="gitcode-login-divider">—— 或 ——</div>';
    echo '<a href="' . esc_url($url) . '" class="gitcode-login-btn">GitCode 账号登录</a>';
}

前端注入:适配任意主题

标准做法是只往 wp-login.php 加按钮就够了。但 AeroCore 主题把登录入口放在了头部导航栏,通过 #login-trigger 元素 + 弹窗实现——没有走 WordPress 原生登录页。

要在这旁边放 GitCode 按钮,就得用 JavaScript 在 wp_footer 动态注入:

代码语言:javascript
复制
add_action('wp_footer', [__CLASS__, 'inject_frontend_button']);

public static function inject_frontend_button()
{
    if (is_user_logged_in()) return;
    $login_url = esc_url(wp_login_url() . '?action=gitcode_login');
    ?>
    <script>
    (function(){
        var btn = document.createElement('a');
        btn.href = '<?php echo $login_url; ?>';
        btn.title = 'GitCode 账号登录';
        
        function tryInject() {
            var target = document.getElementById('login-trigger');
            if (!target) target = document.querySelector('.header-actions .user-avatar-placeholder');
            if (!target) target = document.querySelector('a[href*="wp-login.php"]');
            if (target && target.parentNode) {
                target.parentNode.insertBefore(btn, target.nextSibling);
            }
        }
        
        // 多重试机制,应对异步渲染
        setTimeout(tryInject, 500);
        setTimeout(tryInject, 2000);
        setTimeout(tryInject, 5000);
    })();
    </script>
    <?php
}

这里用了多重试注入策略:500ms、2s、5s 各尝试一次。因为现代主题很多是 Vue / React 渲染的,DOM 就绪时机不固定。三次尝试覆盖了绝大多数场景。

按钮样式:32×32 黑色圆角方块,内嵌珊瑚红 G 字 SVG Logo,和深色主题风格完美融合。

短码支持

已登录:站长 | 退出

短码把登录按钮放在文章、页面、侧边栏任意位置:

代码语言:javascript
复制
add_shortcode('gitcode_login', [__CLASS__, 'shortcode_button']);

public static function shortcode_button()
{
    if (is_user_logged_in()) {
        return '已登录:' . esc_html(wp_get_current_user()->display_name);
    }
    $url = wp_login_url() . '?action=gitcode_login';
    return '<a href="' . esc_url($url) . '">GitCode 账号登录</a>';
}

Token 生命周期管理

GitCode Access Token 有效期有限,但提供了 refresh_token(有效期 15 天)。插件在每次成功登录时持久化:

代码语言:javascript
复制
update_user_meta($user_id, 'gcol_access_token',  $token['access_token']);
update_user_meta($user_id, 'gcol_refresh_token', $token['refresh_token']);
update_user_meta($user_id, 'gcol_avatar_url',    $gitcode_user['avatar_url']);
update_user_meta($user_id, 'gcol_profile_url',   $gitcode_user['html_url']);

并提供刷新方法供外部调用:

代码语言:javascript
复制
public static function refresh_token($user_id)
{
    $url = 'https://gitcode.com/oauth/token?' . http_build_query([
        'grant_type'    => 'refresh_token',
        'refresh_token' => get_user_meta($user_id, 'gcol_refresh_token', true),
    ]);
    $response = wp_remote_post($url, ['timeout' => 15]);
    // ... 更新 access_token 和 refresh_token
}

安全措施汇总

开发过程中刻意做了安全左移,把安全问题解决在设计阶段:

措施

说明

State 参数

随机 32 位字符串,transients 存储 5 分钟,回调强制校验,防 CSRF

client_secret 保护

存 options 表,设置页用 password 类型遮罩,不暴露在前端

回调地址锁定

必须在 GitCode 应用配置中精确匹配,防止授权码被劫持

输入过滤

所有来自 GitCode 的返回数据都用 sanitize_* 系列函数过滤

输出转义

所有 HTML 输出都用 esc_html / esc_url / esc_attr 转义

auto_register 开关

管理员可按需关闭,防止未授权用户自动注册

部署步骤

  1. 前往 GitCode OAuth 应用管理 创建新应用
  2. Redirect URI 填 https://你的博客/wp-login.php?action=gitcode_callback
  3. 将生成的 Client ID 和 Client Secret 填入插件设置页(设置 → GitCode OAuth)
  4. 保存,登录页自动显示"GitCode 账号登录"按钮
  5. 可选:在任意位置放置已登录:站长 | 退出短码

扩展思路

GitCode OAuth 只是一个起点。同样的架构(Settings / OAuth / Profile 三组件分离)可以快速扩展到其他平台:

  • Gitee OAuth:接口几乎一样,换 API 端点即可
  • GitHub OAuth:scope 和端点不同,但流程完全一致
  • 微信开放平台:扫码登录,OAuth 2.0 + OpenID 机制
  • QQ 互联:QQ 登录,也是 OAuth 2.0 授权码流程

总结

一个下午写出来的 GitCode OAuth 登录插件,代码量不大(3 个文件不到 300 行),但覆盖了 OAuth 2.0 完整流程、WordPress 后台设置标准 API、前端 DOM 注入兼容、短码支持和 Token 管理。

核心经验:

  • OAuth 2.0 授权码模式是唯一正确的选择
  • State 校验不能省略——这是防 CSRF 的唯一屏障
  • 三策略用户匹配让登录体验无缝——老用户、已有账号用户、新用户各走各路
  • 前端注入用多重试——不要赌 DOM 渲染时机
  • 安全左移——在设计阶段就把输入过滤、输出转义、权限控制做好

完整代码已开源在 GitCode:gitcode.com/zqwlkeji/gitcode-oauth-login,欢迎 Star、Fork、提 Issue,直接拿去用或魔改。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2026-06-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 为什么选 GitCode?
  • OAuth 2.0 授权码流程
    • 第一步:构造授权请求
    • 第二步:用授权码换 Access Token
    • 第三步:用 Access Token 获取用户信息
    • 第四步:匹配或创建 WordPress 账号
  • 插件架构设计
    • 入口:单例模式 + 配置集中管理
    • 设置页面:标准 WordPress Settings API
    • WordPress 登录页按钮
  • 前端注入:适配任意主题
  • 短码支持
  • Token 生命周期管理
  • 安全措施汇总
  • 部署步骤
  • 扩展思路
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档