给 Typecho 评论区适配 Cloudflare Turnstile

摘要:一直以来,本站评论区都饱受 Spam 的烦扰,于是 TE 水友群里就有小伙伴提议用一下 Cloudflare Turnstile 来解决一下。这个就是类似于 Google reCAPTCHA 吧,但区别与 Google 的是,Turnstile 没有那些烦人的

一直以来,本站评论区都饱受 Spam 的烦扰,于是 TE 水友群里就有小伙伴提议用一下 Cloudflare Turnstile 来解决一下。这个就是类似于 Google reCAPTCHA 吧,但区别与 Google 的是,Turnstile 没有那些烦人的找红绿灯找自行车啊什么的,几乎属于无感的。于是便着手考虑给自己站点的评论区也安排上这个。

首先,要到 Cloudflare Turnstile 官网注册一下,创建好 Turnstile 站点,获取到两个密钥(一个 Key 是放在前台的,另一个打码的是放在后台的)

免费的额度肯定够用,具体可以详见官网。但免费的版本“仅限托管模式”,也就是不能无痕插入,肯定会在前端留出一个验证状态的框,可能会对美观性造成一定影响(比如说我这边就是)

在主题目录的 comments.php 中,找到 表单,把下面的代码放到表单里面。如果实在确定不好位置,那就放在评论提交按钮的上面就好。记得把上面的前台密钥给填写进去(不是打码的那个)。

对于进行过评论区 Ajax 提交改造的站点,需要让验证器在每次提交之后,进行一次刷新的操作。可以在适当位置添加如下代码。

// 也可以不用 try 包裹try { turnstile.reset;} catch (e) {}

直接在主题目录的 functions.php 中,追加如下内容。

Typecho_Plugin::factory('Widget_Feedback')->comment = ['XComment', 'feedbackFilter'];class XComment { /** * 评论发布钩子 * @param $comment * @param $archive * @return mixed * @throws \Typecho\Widget\Exception */ public static function feedbackFilter($comment, $archive) { // 如果已登录,直接返回,不进行处理 if (Typecho_Widget::widget('Widget_User')->hasLogin) { return $comment; } $secret = '打码的密钥填在这里'; /* Store this somewhere secure */ $remote_addr = $_SERVER['REMOTE_ADDR']; $cf_url = 'https://challenges.cloudflare.com/turnstile/v0/siteverify'; $token = $_POST['cf-turnstile-response']; $msg = ''; $isPass = false; // request data $data = array( "secret" => $secret, "response" => $token, "remoteip" => $remote_addr ); // Initialize cURL $curl = curl_init; // Set the cURL options curl_setopt($curl, CURLOPT_URL, $cf_url); curl_setopt($curl, CURLOPT_POST, true); curl_setopt($curl, CURLOPT_POSTFIELDS, $data); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); // Execute the cURL request $response = curl_exec($curl); // Check for errors if (curl_errno($curl)) { $error_message = curl_error($curl); // Handle the error the way you like it $msg = '[Turnstile]cURL Error: ' . $error_message; }else{ /* Parse Cloudflare's response and check if there are any validation errors */ $response = json_decode($response,true); if ($response['error-codes'] && count($response['error-codes']) > 0){ $msg = '此评论已被 Cloudflare Turnstile 拦截。Error codes: '; foreach($response['error-codes'] as $e){ $msg .= $e; } }else{ $isPass = true; } } // Close cURL curl_close($curl); if ($isPass) { return $comment; } else { throw new \Typecho\Widget\Exception(_t($msg, '评论失败')); } }}

这样下来,应该就可以了。

来源:Web3软件开发一点号

相关推荐