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

WordPress在线课程:基于Token的无账号访问与进度追踪方案咨询

无注册用户的WordPress课程访问控制与进度追踪方案

针对你提到的无需注册即可控制课程访问、追踪学习进度的需求,我有过类似实践,以下是具体实现方案和关键注意事项:

一、核心Token与个性化URL生成

  • Token结构设计:采用「用户标识-课程ID-时间戳-HMAC签名」的组合,避免明文存储敏感信息。用户标识可以是邮箱、自定义短ID(比如给每个需访问的用户生成唯一标识),签名用WordPress内置的wp_hash()函数生成,确保Token无法被篡改。示例Token:guest_001-105-1718000000-a1b2c3d4e5f6
  • 个性化URL生成:将Token作为查询参数拼接到课程页面URL,比如:https://your-site.com/course/wordpress-basics?access_token=guest_001-105-1718000000-a1b2c3d4e5f6
  • 生成工具:可以在WordPress后台做一个简易生成界面,输入用户标识和课程ID,自动生成带Token的URL,方便批量创建。

二、Token验证与身份识别

在WordPress中通过钩子实现Token验证,确保只有持有有效Token的用户能访问对应课程:

add_action('template_redirect', 'verify_course_access_token');
function verify_course_access_token() {
    // 仅在课程自定义类型页面且存在access_token参数时触发
    if (!is_singular('course') || !isset($_GET['access_token'])) {
        return;
    }

    $token = sanitize_text_field($_GET['access_token']);
    $parts = explode('-', $token);
    
    // 验证Token格式是否正确
    if (count($parts) !== 4) {
        wp_redirect(home_url('/access-denied/'));
        exit;
    }

    list($temp_user_id, $course_id, $timestamp, $signature) = $parts;
    $current_course_id = get_the_ID();

    // 验证Token对应的课程是否为当前访问的课程
    if ((int)$course_id !== $current_course_id) {
        wp_redirect(home_url('/access-denied/'));
        exit;
    }

    // 验证Token有效期(示例:7天)
    if (time() - (int)$timestamp > 7 * 24 * 3600) {
        wp_redirect(home_url('/token-expired/'));
        exit;
    }

    // 重新生成签名,验证Token未被篡改
    $expected_signature = wp_hash("$temp_user_id-$course_id-$timestamp");
    if ($signature !== $expected_signature) {
        wp_redirect(home_url('/invalid-token/'));
        exit;
    }

    // 验证通过,将临时身份存储到会话
    if (!session_id()) {
        session_start();
    }
    $_SESSION['temp_user_id'] = $temp_user_id;
    $_SESSION['allowed_course_id'] = $course_id;
}

三、学习进度追踪实现

  • 自定义数据库表存储进度:创建一张专门的临时进度表,避免和WordPress默认表冲突。可以通过以下SQL语句创建(在主题的functions.php里用dbDelta执行):
add_action('after_setup_theme', 'create_temp_progress_table');
function create_temp_progress_table() {
    global $wpdb;
    $table_name = $wpdb->prefix . 'temp_course_progress';
    $charset_collate = $wpdb->get_charset_collate();

    $sql = "CREATE TABLE $table_name (
        id mediumint(9) NOT NULL AUTO_INCREMENT,
        temp_user_id varchar(50) NOT NULL,
        course_id mediumint(9) NOT NULL,
        completed_chapters text NOT NULL,
        total_time int(11) DEFAULT 0,
        last_access datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
        PRIMARY KEY  (id),
        UNIQUE KEY temp_user_course (temp_user_id, course_id)
    ) $charset_collate;";

    require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
    dbDelta($sql);
}
  • 进度更新触发:通过前端AJAX请求,在用户完成章节、观看完视频等操作时,调用后端接口更新进度:
// 注册AJAX接口(允许未登录用户调用)
add_action('wp_ajax_update_course_progress', 'update_course_progress');
add_action('wp_ajax_nopriv_update_course_progress', 'update_course_progress');

function update_course_progress() {
    // 验证临时身份
    if (!session_id()) {
        session_start();
    }
    if (!isset($_SESSION['temp_user_id']) || !isset($_SESSION['allowed_course_id'])) {
        wp_send_json_error('未授权访问');
        exit;
    }

    $temp_user_id = sanitize_text_field($_SESSION['temp_user_id']);
    $course_id = (int)$_SESSION['allowed_course_id'];
    $chapter_id = sanitize_text_field($_POST['chapter_id']);
    $add_time = (int)$_POST['add_time']; // 本次学习时长,单位秒

    global $wpdb;
    $table_name = $wpdb->prefix . 'temp_course_progress';

    // 查询现有进度
    $existing_progress = $wpdb->get_row($wpdb->prepare(
        "SELECT completed_chapters, total_time FROM $table_name WHERE temp_user_id = %s AND course_id = %d",
        $temp_user_id, $course_id
    ));

    // 更新已完成章节(用逗号分隔存储)
    $completed_chapters = $existing_progress ? $existing_progress->completed_chapters : '';
    if (!str_contains($completed_chapters, $chapter_id)) {
        $completed_chapters = $completed_chapters ? "$completed_chapters,$chapter_id" : $chapter_id;
    }

    // 更新总学习时长
    $total_time = $existing_progress ? $existing_progress->total_time + $add_time : $add_time;

    // 插入或更新进度记录
    $wpdb->replace(
        $table_name,
        array(
            'temp_user_id' => $temp_user_id,
            'course_id' => $course_id,
            'completed_chapters' => $completed_chapters,
            'total_time' => $total_time
        ),
        array('%s', '%d', '%s', '%d')
    );

    wp_send_json_success('进度更新成功');
}
  • 进度展示:在课程页面读取当前用户的进度数据,展示已完成章节、学习时长等信息:
function get_temp_user_progress() {
    if (!session_id()) {
        session_start();
    }
    if (!isset($_SESSION['temp_user_id']) || !isset($_SESSION['allowed_course_id'])) {
        return false;
    }

    global $wpdb;
    $table_name = $wpdb->prefix . 'temp_course_progress';
    $progress = $wpdb->get_row($wpdb->prepare(
        "SELECT * FROM $table_name WHERE temp_user_id = %s AND course_id = %d",
        $_SESSION['temp_user_id'], $_SESSION['allowed_course_id']
    ));

    return $progress;
}

在课程模板中调用这个函数,渲染进度信息即可。

四、关键注意事项(已知安全性不足前提下)

  • Token转发风险:因为URL可直接分享,任何人拿到链接都能访问对应课程。可以通过设置Token有效期(比如7天)降低风险,或者在生成URL时提示用户不要转发。
  • 会话管理:确保会话在用户关闭浏览器后失效,避免他人复用会话访问。如果服务器端会话配置有问题,可以改用临时Cookie存储身份信息,设置较短的过期时间。
  • 数据清理:定期清理过期的进度记录(比如删除3个月未访问的记录),避免数据库冗余。
  • 性能优化:如果用户量较大,建议给临时进度表的temp_user_id和course_id字段建立联合索引,提升查询速度。
  • 权限兼容:确保WordPress的默认权限系统不会拦截临时用户的AJAX请求,比如在wp_ajax_nopriv_*钩子中处理未登录用户的请求。
  • 统计需求:如果需要汇总学习数据,提前设计好表结构,方便后续导出或统计分析。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 11:57:18