mindforce/attempt

此包的最新版本(dev-master)没有提供许可证信息。

CakePHP插件,用于帮助保护敏感操作免受暴力攻击。

安装次数: 1,379

依赖者: 0

建议者: 0

安全: 0

星标: 0

关注者: 3

分支: 9

类型:cakephp-plugin

dev-master 2015-10-18 19:13 UTC

This package is not auto-updated.

Last update: 2024-09-14 19:03:54 UTC


README

CakePHP 2.0或2.1插件,帮助保护敏感操作免受暴力攻击。

API

count($action)

返回特定操作的失败尝试次数。

limit($action, $limit = 5)

如果失败尝试次数超过传递的限制,则返回false。

fail($action, $duration = '+10 minutes')

创建一个失败尝试,该尝试在指定时间内计入限制。

reset($action)

删除特定操作的 所有失败尝试。

cleanup()

从数据库中删除所有过期的失败尝试。这应该通过CakeShell(理想情况下作为CRON作业)定期运行。

数据库模式

运行 Console/cake schema create --plugin Attempt 或手动创建一个表

CREATE TABLE `attempts` (
  `id` char(36) NOT NULL DEFAULT '',
  `ip` varchar(64) DEFAULT NULL,
  `action` varchar(32) DEFAULT NULL,
  `created` datetime DEFAULT NULL,
  `expires` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `ip` (`ip`,`action`),
  KEY `expires` (`expires`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8

示例实现

<?php
class ExampleController extends AppController {
    
    public $components = array(
        'Attempt.Attempt'
    );
    
    public $loginAttemptLimit = 10;
    public $loginAttemptDuration = '+1 hour';
    
    public function login() {
        // Form submitted?
        if ( $formSubmitted = true ) {
            // All required fields entered?
            if ( $validFormData = true ) {
                // Limit to 10 failed attempts
                if ( $this->Attempt->limit('login', $this->loginAttemptLimit) ) {
                    // Validate user credentials
                    if ( $validCredentials = true ) {
                        // Log user in
                    } else {
                        // Invalid credentials, count as failed attempt for an hour
                        $this->Attempt->fail('login', $this->loginAttemptDuration);
                        $this->Session->setFlash('Unknown user or wrong password');
                    }
                } else {
                    // User exceeded attempt limit
                    // Ideally show a CAPTCHA (ensuring this is not a robot 
                    // without blocking out and frustrating users),
                    // otherwise show error message
                    $this->Session->setFlash('Too many failed attempts!');
                }
            } else {
                // Invalid form data but keep it ambiguous
                $this->Session->setFlash('Unknown user or wrong password');
            }
        }
    }
}

替代实现(简单的管理员登录)

<?php
class UsersController extends AppController {
    
    public $components = array(
        'Security',
        'Attempt.Attempt'
    );
    
    public $loginAttemptLimit = 10;
    public $loginAttemptDuration = '+1 hour';

    public function admin_login() {
        if (empty($this->data)) {
            return;
        }
        // check for repeated login attempts
        if ($this->Attempt->limit('admin_login', $this->loginAttemptLimit)) {
            if ($this->request->is('post')) {
                if ($this->Auth->login()) {
                    // login was successful, redirect to admin menu
                    $this->redirect(array(
                        'controller' => 'users',
                        'action' => 'index',
                        'admin' => true
                    ));
                } else {
                    // increment the attempt counter
                    $this->Attempt->fail('admin_login', $this->loginAttemptDuration);
                    $this->Session->setFlash('Unknown user or wrong password.');
                    return;
                }
            }
        } else {
            // $loginAttemptLimit reached
            $this->Session->setFlash('Login limit exceeded, please try again later.');
        }
    }
}