menu LittleJake's Blog
color_lens
avatar
Jake Liu
Never Settle
creative commons by-nc-sa
hit
Category
keyboard_arrow_down

© 2024 LittleJake's Blog.

萌ICP备20223020号

给Typecho添加谷歌验证码


20200203225535.png

介绍

最近对于WordPress的博客框架爆破事件层出不穷,必须加个验证码防止爆破。反正我是没搞懂用WordPress的爆破来爆破Typecho是什么心态。

准备工作

  • 谷歌验证码API
  • 中国境内使用reCaptcha的镜像

处理方法

var/Widget/Login.php中找到action方法,对比修改添加。

    /**
     * 初始化函数
     *
     * @access public
     * @return void
     */
    public function action()
    {
        // protect
        $this->security->protect();

        /** 如果已经登录 */
        if ($this->user->hasLogin()) {
            /** 直接返回 */
            $this->response->redirect($this->options->index);
        }


        /** 初始化验证类 */
        $validator = new Typecho_Validate();
        $validator->addRule('name', 'required', _t('请输入用户名'));
        $validator->addRule('password', 'required', _t('请输入密码'));
        $validator->addRule('g-recaptcha-response', 'required', _t('请输入验证码'));   //加入

        /** 截获验证异常 */
        if ($error = $validator->run($this->request->from('name', 'password', 'g-recaptcha-response'))) {
            Typecho_Cookie::set('__typecho_remember_name', $this->request->name);

            /** 设置提示信息 */
            $this->widget('Widget_Notice')->set($error);
            $this->response->goBack();
        }

        /** 开始验证用户 **/
        /** Google reCaptcha v2 */
        //加入
        $post_data = [        
            'secret' => '你的Google API密钥',        
            'response' => $_POST["g-recaptcha-response"]
        ];
        $recaptcha_json_result = $this->send_post('https://www.google.com/recaptcha/api/siteverify', $post_data);   
        $recaptcha_result = json_decode($recaptcha_json_result, true);



        if(!$recaptcha_result['success']){
            /** 设置提示信息 */
            $this->widget('Widget_Notice')->set(_t('请输入验证码'));
            $this->response->goBack();
        }

        $valid = $this->user->login($this->request->name, $this->request->password,
        false, 1 == $this->request->remember ? $this->options->time + $this->options->timezone + 30*24*3600 : 0);

        /** 比对密码 */
        if (!$valid) {
            /** 防止穷举,休眠3秒 */
            sleep(3);

            $this->pluginHandle()->loginFail($this->user, $this->request->name,
            $this->request->password, 1 == $this->request->remember);

            Typecho_Cookie::set('__typecho_remember_name', $this->request->name);
            $this->widget('Widget_Notice')->set(_t('用户名或密码无效'), 'error');
            $this->response->goBack('?referer=' . urlencode($this->request->referer));
        }

        $this->pluginHandle()->loginSucceed($this->user, $this->request->name,
        $this->request->password, 1 == $this->request->remember);

        /** 跳转验证后地址 */
        if (NULL != $this->request->referer) {
            $this->response->redirect($this->request->referer);
        } else if (!$this->user->pass('contributor', true)) {
            /** 不允许普通用户直接跳转后台 */
            $this->response->redirect($this->options->profileUrl);
        } else {
            $this->response->redirect($this->options->adminUrl);
        }
    }

文件末尾添加一个send_post的方法

    private function send_post($url, $post_data)
    {
        $postdata = http_build_query($post_data);
        $options = array(
            'http' => array(
                'method' => 'POST',
                'header' => 'Content-type:application/x-www-form-urlencoded',
                'content' => $postdata,
                'timeout' => 20 // 超时时间(单位:s)
            )
        );
        $context = stream_context_create($options);
        $result = file_get_contents($url, false, $context);
        return $result;
    }

对于前台的页面,打开admin/Login.php
在密码的p标签下另起一行插入

            <p>
                <label for="password" class="sr-only"><?php _e('密码'); ?></label>
                <input type="password" id="password" name="password" class="text-l w-100" placeholder="<?php _e('密码'); ?>" />
            </p>
            <!-- 插入 -->
            <div class="g-recaptcha" data-sitekey="6LfU4dIUAAAAADFaigTFmhuYUYXvkMYC5t3HnAvr"></div>
            <p class="submit">
                <button type="submit" class="btn btn-l w-100 primary"><?php _e('登录'); ?></button>
                <input type="hidden" name="referer" value="<?php echo htmlspecialchars($request->get('referer')); ?>" />
            </p>

在底部footer前插入script标签

<script>
$(document).ready(function () {
    $('#name').focus();
});
</script>
<!-- 插入 -->
<script src="https://www.recaptcha.net/recaptcha/api.js" async defer></script>
<?php
include 'footer.php';
?>

Buy me a beer
Jake Liu
Never Settle

Title: 给Typecho添加谷歌验证码

Author: Jake Liu

Origin:

Creative Commons License

This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0) For any re-post you must give appropriate credit.

文章遵循CC许可 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 转载请注明出处

Tag:typecho, google, captcha, recaptcha

评论区

Add a new comment.

Theme