pictcode / app / Plugin / Recaptcha / Controller / Component / RecaptchaComponent.php @ master
履歴 | 表示 | アノテート | ダウンロード (4.564 KB)
1 |
<?php
|
---|---|
2 |
/**
|
3 |
* Copyright 2009-2014, Cake Development Corporation (http://cakedc.com)
|
4 |
*
|
5 |
* Licensed under The MIT License
|
6 |
* Redistributions of files must retain the above copyright notice.
|
7 |
*
|
8 |
* @copyright Copyright 2009-2014, Cake Development Corporation (http://cakedc.com)
|
9 |
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
10 |
*/
|
11 |
|
12 |
App::uses('HttpSocket', 'Network/Http'); |
13 |
|
14 |
/**
|
15 |
* CakePHP Recaptcha component
|
16 |
*
|
17 |
* @package recaptcha
|
18 |
* @subpackage recaptcha.controllers.components
|
19 |
*/
|
20 |
|
21 |
class RecaptchaComponent extends Component { |
22 |
|
23 |
/**
|
24 |
* Name
|
25 |
*
|
26 |
* @var string
|
27 |
*/
|
28 |
public $Controller = null; |
29 |
|
30 |
/**
|
31 |
* Recaptcha API Url
|
32 |
*
|
33 |
* @var string
|
34 |
*/
|
35 |
public $apiUrl = 'http://www.google.com/recaptcha/api/verify'; |
36 |
|
37 |
/**
|
38 |
* Private API Key
|
39 |
*
|
40 |
* @var string
|
41 |
*/
|
42 |
public $privateKey = ''; |
43 |
|
44 |
/**
|
45 |
* Error coming back from Recaptcha
|
46 |
*
|
47 |
* @var string
|
48 |
*/
|
49 |
public $error = null; |
50 |
|
51 |
/**
|
52 |
* Actions that should automatically checked for a recaptcha input
|
53 |
*
|
54 |
* @var array
|
55 |
*/
|
56 |
public $actions = array(); |
57 |
|
58 |
/**
|
59 |
* Settings
|
60 |
*
|
61 |
* @var array
|
62 |
*/
|
63 |
public $settings = array(); |
64 |
|
65 |
/**
|
66 |
* Default Options
|
67 |
*
|
68 |
* @var array
|
69 |
*/
|
70 |
protected $_defaults = array( |
71 |
'errorField' => 'recaptcha', |
72 |
'actions' => array() |
73 |
); |
74 |
|
75 |
/**
|
76 |
* Constructor
|
77 |
*
|
78 |
* @param ComponentCollection $collection A ComponentCollection this component can use to lazy load its components
|
79 |
* @param array $settings Array of configuration settings
|
80 |
* @return RecaptchaComponent
|
81 |
*/
|
82 |
public function __construct(ComponentCollection $collection, $settings = array()) { |
83 |
parent::__construct($collection, $settings); |
84 |
$this->Controller = $collection->getController(); |
85 |
$this->_defaults['modelClass'] = $this->Controller->modelClass; |
86 |
$this->settings = array_merge($this->_defaults, $settings); |
87 |
$this->actions = array_merge($this->actions, $this->settings['actions']); |
88 |
unset($this->settings['actions']); |
89 |
} |
90 |
|
91 |
/**
|
92 |
* Callback
|
93 |
*
|
94 |
* @param Controller $controller Controller with components to initialize
|
95 |
* @param array $settings Array of configuration settings
|
96 |
* @throws Exception Throws an exception if Recaptchas config is not present
|
97 |
* @return void
|
98 |
*/
|
99 |
public function initialize(Controller $controller, $settings = array()) { |
100 |
if ($controller->name === 'CakeError') { |
101 |
return;
|
102 |
} |
103 |
$this->privateKey = Configure::read('Recaptcha.privateKey'); |
104 |
$this->Controller = $controller; |
105 |
|
106 |
if (!isset($this->Controller->helpers['Recaptcha.Recaptcha'])) { |
107 |
$this->Controller->helpers[] = 'Recaptcha.Recaptcha'; |
108 |
} |
109 |
|
110 |
if (empty($this->privateKey)) { |
111 |
throw new Exception(__d('recaptcha', "You must set your private Recaptcha key using Configure::write('Recaptcha.privateKey', 'your-key');!", true)); |
112 |
} |
113 |
} |
114 |
|
115 |
/**
|
116 |
* Callback
|
117 |
*
|
118 |
* @param Controller $controller Controller with components to initialize
|
119 |
* @return void
|
120 |
*/
|
121 |
public function startup(Controller $controller) { |
122 |
extract($this->settings); |
123 |
$this->Controller->helpers[] = 'Recaptcha.Recaptcha'; |
124 |
$this->Controller->{$modelClass}->Behaviors->load('Recaptcha.Recaptcha', array( |
125 |
'field' => $errorField |
126 |
)); |
127 |
|
128 |
$this->Controller->{$modelClass}->recaptcha = true; |
129 |
if (in_array($this->Controller->action, $this->actions)) { |
130 |
if (!$this->verify()) { |
131 |
$this->Controller->{$modelClass}->recaptcha = false; |
132 |
$this->Controller->{$modelClass}->recaptchaError = $this->error; |
133 |
} |
134 |
} |
135 |
} |
136 |
|
137 |
/**
|
138 |
* Verifies the recaptcha input
|
139 |
*
|
140 |
* Please note that you still have to pass the result to the model and do
|
141 |
* the validation there to make sure the data is not saved!
|
142 |
*
|
143 |
* @return boolean True if the response was correct
|
144 |
*/
|
145 |
public function verify() { |
146 |
if (isset($this->Controller->request->data['recaptcha_challenge_field']) && |
147 |
isset($this->Controller->request->data['recaptcha_response_field'])) { |
148 |
|
149 |
$response = $this->_getApiResponse(); |
150 |
$response = explode("\n", $response->body()); |
151 |
|
152 |
if (empty($response[0])) { |
153 |
$this->error = __d('recaptcha', 'Invalid API response, please contact the site admin.', true); |
154 |
return false; |
155 |
} |
156 |
|
157 |
if ($response[0] === 'true') { |
158 |
return true; |
159 |
} |
160 |
|
161 |
if ($response[1] === 'incorrect-captcha-sol') { |
162 |
$this->error = __d('recaptcha', 'Incorrect captcha', true); |
163 |
} else {
|
164 |
$this->error = $response[1]; |
165 |
} |
166 |
} |
167 |
return false; |
168 |
} |
169 |
|
170 |
/**
|
171 |
* Queries the Recaptcha API and and returns the raw response
|
172 |
*
|
173 |
* @return string
|
174 |
*/
|
175 |
protected function _getApiResponse() { |
176 |
$Socket = new HttpSocket(); |
177 |
return $Socket->post($this->apiUrl, array( |
178 |
'privatekey' => $this->privateKey, |
179 |
'remoteip' => env('REMOTE_ADDR'), |
180 |
'challenge' => $this->Controller->request->data['recaptcha_challenge_field'], |
181 |
'response' => $this->Controller->request->data['recaptcha_response_field'] |
182 |
)); |
183 |
} |
184 |
|
185 |
} |