recaptcha 0.3.6 → 5.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: a2ab60ab04802c7dc8a205ffa010071d2edd9f47
4
- data.tar.gz: 7155b2dcb7ee6c183b3a06b6768562daf6e3e2da
2
+ SHA256:
3
+ metadata.gz: 849f0b2edee6bde557c0bdab3802dfbc7528a5e777709a110b6c4f228842c1a1
4
+ data.tar.gz: ebf65ad28a50a06363bc7544df1ef2639aefebbeace7f15cd97fd1ffc047764c
5
5
  SHA512:
6
- metadata.gz: b2dcd0d13ae9dcbb8f9c96a7c65e0231f058a7979696bd181fe101640f5c3778d02b8dbb39d898f2bcd2a788b1ab062dbb0b027619d71a6c55af9e2e8a0cf151
7
- data.tar.gz: c55e6b3701db18b477ea056b289ec710e550daa71dfe3d03c3540ebdd8e22adef22969fac2013bc0b8586cb65ec89acef72200984fa1765d119b83568676d9aa
6
+ metadata.gz: 68f606e91517a8062d7afe48e43d306383f4ef4c83ac4c61179f9ea58d38628230768865604a61758bfd3d5b0d1a2197a981b764169153e36ef0bcf7bedb86d9
7
+ data.tar.gz: c87318df857db04fb2485c73ba686d82f3d18ed87cc0db8f006bbe2f456179218aeb25b1477017b80240504329cc9d02acd9b09457ae927997a5b61dd6849228
data/CHANGELOG.md ADDED
@@ -0,0 +1,141 @@
1
+ ## Next
2
+
3
+ ## 5.5.0
4
+ * add `recaptcha_reply` controller method for better debugging/inspection
5
+
6
+ ## 5.4.1
7
+ * fix v2 vs 'data' postfix
8
+
9
+ ## 5.4.0
10
+ * added 'data' postfix to g-recaptcha-response attribute name to avoid collisions
11
+
12
+ ## 5.3.0
13
+ * turbolinks support
14
+
15
+ ## 5.2.0
16
+ * remove dependency on rails methods
17
+
18
+ ## 5.1.0
19
+ * Added default translations for rails/i18n
20
+ * use recaptcha.net for the script tag
21
+
22
+ ## 5.0.0
23
+ * Changed host to Recaptcha.net
24
+ * Add v3 API support
25
+ * Renamed `Recaptcha::ClientHelper` to `Recaptcha::Adapters::ViewMethods`
26
+ * Renamed `Recaptcha::Verify` to `Recaptcha::Adapters::ControllerMethods`
27
+
28
+ ## 4.12.0 - 2018-08-30
29
+ * add `input` option to `invisible_recaptcha_tags`'s `ui` setting
30
+
31
+ ## 4.11.1 - 2018-08-08
32
+ * leave `tabindex` attribute alone for `invisible_recaptcha_tags`
33
+
34
+ ## 4.11.0 - 2018-08-06
35
+ * prefer RAILS_ENV over RACK_ENV #286
36
+
37
+ ## 4.0.0 - 2016-11-14
38
+ * public_key -> site_key and private_key -> secret_key
39
+
40
+ ## 3.4.0 - 2016-11-01
41
+ * Update fallback html
42
+
43
+ ## 3.2.0 - 2016-06-13
44
+ * remove SKIP_VERIFY_ENV constant, use `skip_verify_env` instance variable instead
45
+
46
+ ## 3.1.0 - 2016-06-10
47
+ * better error messages
48
+ * frozen constants
49
+
50
+ ## 3.0.0 - 2016-05-27
51
+ * remove all non-ssl options
52
+
53
+ ## 2.3.0 - 2016-05-25
54
+ * enable ssl verification by default ... disable via `disable_ssl_verification = true`
55
+
56
+ ## 2.2.0 - 2016-05-23
57
+ * Add global hostname validator config
58
+ * Clean up after with_configuration exception
59
+
60
+ ## 2.1.0 - 2016-05-19
61
+ * do not query google if repactcha was not submitted
62
+
63
+ ## 2.0.0 - 2016-05-17
64
+ * remove stoken support, must use custom domain verification or domain whitelist
65
+
66
+ ## 1.3.0 - 2016-04-07
67
+ * do not set model error and flash
68
+
69
+ ## 1.2.0 - 2016-04-01
70
+ * custom domain validation
71
+
72
+ ## 1.1.0 - 2016-01-27
73
+ * support RACK_ENV
74
+
75
+ ## 1.0.2 - 2015-11-30
76
+ * nice deprecations for api_version
77
+
78
+ ## 1.0.1 - 2015-11-30
79
+ * no longer defines `Rails` when `recaptcha/rails` is required
80
+
81
+ ## 1.0.0 - 2015-11-30
82
+ * remove api v1 support
83
+ * remove ssl_api_server_url, nonssl_api_server_url, change api_server_url to always need ssl option
84
+ * removed activesupport dependency for .to_query
85
+ * made flash and models both have descriptive errors
86
+
87
+ ## 0.6.0 - 2015-11-19
88
+ * extract token module
89
+ * need to use `gem "recaptcha", require: "recaptcha/rails"` to get rails helpers installed
90
+
91
+ ## 0.5.0 - 2015-11-18
92
+ * size option
93
+ * support disabling stoken
94
+ * support Rails.env
95
+
96
+ ## 0.4.0 / 2015-03-22
97
+
98
+ * Add support for ReCaptcha v2 API
99
+ * V2 API requires `g-recaptcha-response` parameters; https://github.com/ambethia/recaptcha/pull/114
100
+
101
+ ## 0.3.6 / 2012-01-07
102
+
103
+ * Many documentation changes
104
+ * Fixed deprecations in dependencies
105
+ * Protocol relative JS includes
106
+ * Fixes for options hash
107
+ * Fixes for failing tests
108
+
109
+ ## 0.3.5 / 2012-05-02
110
+
111
+ * I18n for error messages
112
+ * Rails: delete flash keys if unused
113
+
114
+ ## 0.3.4 / 2011-12-13
115
+
116
+ * Rails 3
117
+ * Remove jeweler
118
+
119
+ ## 0.2.2 / 2009-09-14
120
+
121
+ * Add a timeout to the validator
122
+ * Give the documentation some love
123
+
124
+ ## 0.2.1 / 2009-09-14
125
+
126
+ * Removed Ambethia namespace, and restructured classes a bit
127
+ * Added an example rails app in the example-rails branch
128
+
129
+ ## 0.2.0 / 2009-09-12
130
+
131
+ * RecaptchaOptions AJAX API Fix
132
+ * Added 'cucumber' as a test environment to skip
133
+ * Ruby 1.9 compat fixes
134
+ * Added option :message => 'Custom error message' to verify_recaptcha
135
+ * Removed dependency on ActiveRecord constant
136
+ * Add I18n
137
+
138
+ ## 0.1.0 / 2008-2-8
139
+
140
+ * 1 major enhancement
141
+ * Initial Gem Release
data/README.md ADDED
@@ -0,0 +1,520 @@
1
+ # reCAPTCHA
2
+ [![Gem Version](https://badge.fury.io/rb/recaptcha.svg)](https://badge.fury.io/rb/recaptcha)
3
+
4
+ Author: Jason L Perry (http://ambethia.com)<br/>
5
+ Copyright: Copyright (c) 2007-2013 Jason L Perry<br/>
6
+ License: [MIT](http://creativecommons.org/licenses/MIT/)<br/>
7
+ Info: https://github.com/ambethia/recaptcha<br/>
8
+ Bugs: https://github.com/ambethia/recaptcha/issues<br/>
9
+
10
+ This gem provides helper methods for the [reCAPTCHA API](https://www.google.com/recaptcha). In your
11
+ views you can use the `recaptcha_tags` method to embed the needed javascript, and you can validate
12
+ in your controllers with `verify_recaptcha` or `verify_recaptcha!`, which raises an error on
13
+ failure.
14
+
15
+ ## Obtaining a key
16
+
17
+ Go to the [reCAPTCHA admin console](https://www.google.com/recaptcha/admin) to obtain a reCAPTCHA API key.
18
+
19
+ The reCAPTCHA type(s) that you choose for your key will determine which methods to use below.
20
+
21
+ | reCAPTCHA type | Methods to use | Description |
22
+ |----------------------------------------------|----------------|-------------|
23
+ | v3 | [`recaptcha_v3`](#recaptcha_v3) | Verify requests with a [score](https://developers.google.com/recaptcha/docs/v3#score)
24
+ | v2 Checkbox<br/>("I'm not a robot" Checkbox) | [`recaptcha_tags`](#recaptcha_tags) | Validate requests with the "I'm not a robot" checkbox |
25
+ | v2 Invisible<br/>(Invisible reCAPTCHA badge) | [`invisible_recaptcha_tags`](#invisible_recaptcha_tags) | Validate requests in the background |
26
+
27
+ Note: You can _only_ use methods that match your key's type. You cannot use v2 methods with a v3
28
+ key or use `recaptcha_tags` with a v2 Invisible key, for example. Otherwise you will get an
29
+ error like "Invalid key type" or "This site key is not enabled for the invisible captcha."
30
+
31
+ Note: Enter `localhost` or `127.0.0.1` as the domain if using in development with `localhost:3000`.
32
+
33
+ ## Rails Installation
34
+
35
+ ```ruby
36
+ gem "recaptcha"
37
+ ```
38
+
39
+ You can keep keys out of the code base with environment variables or with Rails [secrets](https://api.rubyonrails.org/classes/Rails/Application.html#method-i-secrets).<br/>
40
+
41
+ In development, you can use the [dotenv](https://github.com/bkeepers/dotenv) gem. (Make sure to add it above `gem 'recaptcha'`.)
42
+
43
+ See [Alternative API key setup](#alternative-api-key-setup) for more ways to configure or override
44
+ keys. See also the
45
+ [Configuration](https://www.rubydoc.info/github/ambethia/recaptcha/master/Recaptcha/Configuration)
46
+ documentation.
47
+
48
+ ```shell
49
+ export RECAPTCHA_SITE_KEY = '6Lc6BAAAAAAAAChqRbQZcn_yyyyyyyyyyyyyyyyy'
50
+ export RECAPTCHA_SECRET_KEY = '6Lc6BAAAAAAAAKN3DRm6VA_xxxxxxxxxxxxxxxxx'
51
+ ```
52
+
53
+ Add `recaptcha_tags` to the forms you want to protect:
54
+
55
+ ```erb
56
+ <%= form_for @foo do |f| %>
57
+ # …
58
+ <%= recaptcha_tags %>
59
+ # …
60
+ <% end %>
61
+ ```
62
+
63
+ Then, add `verify_recaptcha` logic to each form action that you've protected:
64
+
65
+ ```ruby
66
+ # app/controllers/users_controller.rb
67
+ @user = User.new(params[:user].permit(:name))
68
+ if verify_recaptcha(model: @user) && @user.save
69
+ redirect_to @user
70
+ else
71
+ render 'new'
72
+ end
73
+ ```
74
+
75
+ ## Sinatra / Rack / Ruby installation
76
+
77
+ See [sinatra demo](/demo/sinatra) for details.
78
+
79
+ - add `gem 'recaptcha'` to `Gemfile`
80
+ - set env variables
81
+ - `include Recaptcha::Adapters::ViewMethods` where you need `recaptcha_tags`
82
+ - `include Recaptcha::Adapters::ControllerMethods` where you need `verify_recaptcha`
83
+
84
+
85
+ ## reCAPTCHA v2 API and Usage
86
+
87
+ ### `recaptcha_tags`
88
+
89
+ Use this when your key's reCAPTCHA type is "v2 Checkbox".
90
+
91
+ The following options are available:
92
+
93
+ | Option | Description |
94
+ |---------------------|-------------|
95
+ | `:theme` | Specify the theme to be used per the API. Available options: `dark` and `light`. (default: `light`) |
96
+ | `:ajax` | Render the dynamic AJAX captcha per the API. (default: `false`) |
97
+ | `:site_key` | Override site API key from configuration |
98
+ | `:error` | Override the error code returned from the reCAPTCHA API (default: `nil`) |
99
+ | `:size` | Specify a size (default: `nil`) |
100
+ | `:nonce` | Optional. Sets nonce attribute for script. Can be generated via `SecureRandom.base64(32)`. (default: `nil`) |
101
+ | `:id` | Specify an html id attribute (default: `nil`) |
102
+ | `:callback` | Optional. Name of success callback function, executed when the user submits a successful response |
103
+ | `:expired_callback` | Optional. Name of expiration callback function, executed when the reCAPTCHA response expires and the user needs to re-verify. |
104
+ | `:error_callback` | Optional. Name of error callback function, executed when reCAPTCHA encounters an error (e.g. network connectivity) |
105
+ | `:noscript` | Include `<noscript>` content (default: `true`)|
106
+
107
+ [JavaScript resource (api.js) parameters](https://developers.google.com/recaptcha/docs/invisible#js_param):
108
+
109
+ | Option | Description |
110
+ |---------------------|-------------|
111
+ | `:onload` | Optional. The name of your callback function to be executed once all the dependencies have loaded. (See [explicit rendering](https://developers.google.com/recaptcha/docs/display#explicit_render)) |
112
+ | `:render` | Optional. Whether to render the widget explicitly. Defaults to `onload`, which will render the widget in the first g-recaptcha tag it finds. (See [explicit rendering](https://developers.google.com/recaptcha/docs/display#explicit_render)) |
113
+ | `:hl` | Optional. Forces the widget to render in a specific language. Auto-detects the user's language if unspecified. (See [language codes](https://developers.google.com/recaptcha/docs/language)) |
114
+ | `:script` | Alias for `:external_script`. If you do not need to add a script tag by helper you can set the option to `false`. It's necessary when you add a script tag manualy (default: `true`). |
115
+ | `:external_script` | Set to `false` to avoid including a script tag for the external `api.js` resource. Useful when including multiple `recaptcha_tags` on the same page. |
116
+ | `:script_async` | Set to `false` to load the external `api.js` resource synchronously. (default: `true`) |
117
+ | `:script_defer` | Set to `true` to defer loading of external `api.js` until HTML documen has been parsed. (default: `true`) |
118
+
119
+ Any unrecognized options will be added as attributes on the generated tag.
120
+
121
+ You can also override the html attributes for the sizes of the generated `textarea` and `iframe`
122
+ elements, if CSS isn't your thing. Inspect the [source of `recaptcha_tags`](https://github.com/ambethia/recaptcha/blob/master/lib/recaptcha/helpers.rb)
123
+ to see these options.
124
+
125
+ Note that you cannot submit/verify the same response token more than once or you will get a
126
+ `timeout-or-duplicate` error code. If you need reset the captcha and generate a new response token,
127
+ then you need to call `grecaptcha.reset()`.
128
+
129
+ ### `verify_recaptcha`
130
+
131
+ This method returns `true` or `false` after processing the response token from the reCAPTCHA widget.
132
+ This is usually called from your controller, as seen [above](#rails-installation).
133
+
134
+ Passing in the ActiveRecord object via `model: object` is optional. If you pass a `model`—and the
135
+ captcha fails to verify—an error will be added to the object for you to use (available as
136
+ `object.errors`).
137
+
138
+ Why isn't this a model validation? Because that violates MVC. You can use it like this, or how ever
139
+ you like.
140
+
141
+ Some of the options available:
142
+
143
+ | Option | Description |
144
+ |----------------|-------------|
145
+ | `:model` | Model to set errors.
146
+ | `:attribute` | Model attribute to receive errors. (default: `:base`)
147
+ | `:message` | Custom error message.
148
+ | `:secret_key` | Override the secret API key from the configuration.
149
+ | `:timeout` | The number of seconds to wait for reCAPTCHA servers before give up. (default: `3`)
150
+ | `:response` | Custom response parameter. (default: `params['g-recaptcha-response-data']`)
151
+ | `:hostname` | Expected hostname or a callable that validates the hostname, see [domain validation](https://developers.google.com/recaptcha/docs/domain_validation) and [hostname](https://developers.google.com/recaptcha/docs/verify#api-response) docs. (default: `nil`, but can be changed by setting `config.hostname`)
152
+ | `:env` | Current environment. The request to verify will be skipped if the environment is specified in configuration under `skip_verify_env`
153
+
154
+
155
+ ### `invisible_recaptcha_tags`
156
+
157
+ Use this when your key's reCAPTCHA type is "v2 Invisible".
158
+
159
+ For more information, refer to: [Invisible reCAPTCHA](https://developers.google.com/recaptcha/docs/invisible).
160
+
161
+ This is similar to `recaptcha_tags`, with the following additional options that are only available
162
+ on `invisible_recaptcha_tags`:
163
+
164
+ | Option | Description |
165
+ |---------------------|-------------|
166
+ | `:ui` | The type of UI to render for this "invisible" widget. (default: `:button`)<br/>`:button`: Renders a `<button type="submit">` tag with `options[:text]` as the button text.<br/>`:invisible`: Renders a `<div>` tag.<br/>`:input`: Renders a `<input type="submit">` tag with `options[:text]` as the button text. |
167
+ | `:text` | The text to show for the button. (default: `"Submit"`)
168
+ | `:inline_script` | If you do not need this helper to add an inline script tag, you can set the option to `false` (default: `true`).
169
+
170
+ It also accepts most of the options that `recaptcha_tags` accepts, including the following:
171
+
172
+ | Option | Description |
173
+ |---------------------|-------------|
174
+ | `:site_key` | Override site API key from configuration |
175
+ | `:nonce` | Optional. Sets nonce attribute for script tag. Can be generated via `SecureRandom.base64(32)`. (default: `nil`) |
176
+ | `:id` | Specify an html id attribute (default: `nil`) |
177
+ | `:script` | Same as setting both `:inline_script` and `:external_script`. If you only need one or the other, use `:inline_script` and `:external_script` instead. |
178
+ | `:callback` | Optional. Name of success callback function, executed when the user submits a successful response |
179
+ | `:expired_callback` | Optional. Name of expiration callback function, executed when the reCAPTCHA response expires and the user needs to re-verify. |
180
+ | `:error_callback` | Optional. Name of error callback function, executed when reCAPTCHA encounters an error (e.g. network connectivity) |
181
+
182
+ [JavaScript resource (api.js) parameters](https://developers.google.com/recaptcha/docs/invisible#js_param):
183
+
184
+ | Option | Description |
185
+ |---------------------|-------------|
186
+ | `:onload` | Optional. The name of your callback function to be executed once all the dependencies have loaded. (See [explicit rendering](https://developers.google.com/recaptcha/docs/display#explicit_render)) |
187
+ | `:render` | Optional. Whether to render the widget explicitly. Defaults to `onload`, which will render the widget in the first g-recaptcha tag it finds. (See [explicit rendering](https://developers.google.com/recaptcha/docs/display#explicit_render)) |
188
+ | `:hl` | Optional. Forces the widget to render in a specific language. Auto-detects the user's language if unspecified. (See [language codes](https://developers.google.com/recaptcha/docs/language)) |
189
+ | `:external_script` | Set to `false` to avoid including a script tag for the external `api.js` resource. Useful when including multiple `recaptcha_tags` on the same page. |
190
+ | `:script_async` | Set to `false` to load the external `api.js` resource synchronously. (default: `true`) |
191
+ | `:script_defer` | Set to `false` to defer loading of external `api.js` until HTML documen has been parsed. (default: `true`) |
192
+
193
+ ### With a single form on a page
194
+
195
+ 1. The `invisible_recaptcha_tags` generates a submit button for you.
196
+
197
+ ```erb
198
+ <%= form_for @foo do |f| %>
199
+ # ... other tags
200
+ <%= invisible_recaptcha_tags text: 'Submit form' %>
201
+ <% end %>
202
+ ```
203
+
204
+ Then, add `verify_recaptcha` to your controller as seen [above](#rails-installation).
205
+
206
+ ### With multiple forms on a page
207
+
208
+ 1. You will need a custom callback function, which is called after verification with Google's reCAPTCHA service. This callback function must submit the form. Optionally, `invisible_recaptcha_tags` currently implements a JS function called `invisibleRecaptchaSubmit` that is called when no `callback` is passed. Should you wish to override `invisibleRecaptchaSubmit`, you will need to use `invisible_recaptcha_tags script: false`, see lib/recaptcha/client_helper.rb for details.
209
+ 2. The `invisible_recaptcha_tags` generates a submit button for you.
210
+
211
+ ```erb
212
+ <%= form_for @foo, html: {id: 'invisible-recaptcha-form'} do |f| %>
213
+ # ... other tags
214
+ <%= invisible_recaptcha_tags callback: 'submitInvisibleRecaptchaForm', text: 'Submit form' %>
215
+ <% end %>
216
+ ```
217
+
218
+ ```javascript
219
+ // app/assets/javascripts/application.js
220
+ var submitInvisibleRecaptchaForm = function () {
221
+ document.getElementById("invisible-recaptcha-form").submit();
222
+ };
223
+ ```
224
+
225
+ Finally, add `verify_recaptcha` to your controller as seen [above](#rails-installation).
226
+
227
+ ### Programmatically invoke
228
+
229
+ 1. Specify `ui` option
230
+
231
+ ```erb
232
+ <%= form_for @foo, html: {id: 'invisible-recaptcha-form'} do |f| %>
233
+ # ... other tags
234
+ <button type="button" id="submit-btn">
235
+ Submit
236
+ </button>
237
+ <%= invisible_recaptcha_tags ui: :invisible, callback: 'submitInvisibleRecaptchaForm' %>
238
+ <% end %>
239
+ ```
240
+
241
+ ```javascript
242
+ // app/assets/javascripts/application.js
243
+ document.getElementById('submit-btn').addEventListener('click', function (e) {
244
+ // do some validation
245
+ if(isValid) {
246
+ // call reCAPTCHA check
247
+ grecaptcha.execute();
248
+ }
249
+ });
250
+
251
+ var submitInvisibleRecaptchaForm = function () {
252
+ document.getElementById("invisible-recaptcha-form").submit();
253
+ };
254
+ ```
255
+
256
+
257
+ ## reCAPTCHA v3 API and Usage
258
+
259
+ The main differences from v2 are:
260
+ 1. you must specify an [action](https://developers.google.com/recaptcha/docs/v3#actions) in both frontend and backend
261
+ 1. you can choose the minimum score required for you to consider the verification a success
262
+ (consider the user a human and not a robot)
263
+ 1. reCAPTCHA v3 is invisible (except for the reCAPTCHA badge) and will never interrupt your users;
264
+ you have to choose which scores are considered an acceptable risk, and choose what to do (require
265
+ two-factor authentication, show a v3 challenge, etc.) if the score falls below the threshold you
266
+ choose
267
+
268
+ For more information, refer to the [v3 documentation](https://developers.google.com/recaptcha/docs/v3).
269
+
270
+ ### Examples
271
+
272
+ With v3, you can let all users log in without any intervention at all if their score is above some
273
+ threshold, and only show a v2 checkbox recaptcha challenge (fall back to v2) if it is below the
274
+ threshold:
275
+
276
+ ```erb
277
+
278
+ <% if @show_checkbox_recaptcha %>
279
+ <%= recaptcha_tags %>
280
+ <% else %>
281
+ <%= recaptcha_v3(action: 'login', site_key: ENV['RECAPTCHA_SITE_KEY_V3']) %>
282
+ <% end %>
283
+
284
+ ```
285
+
286
+ ```ruby
287
+ # app/controllers/sessions_controller.rb
288
+ def create
289
+ success = verify_recaptcha(action: 'login', minimum_score: 0.5, secret_key: ENV['RECAPTCHA_SECRET_KEY_V3'])
290
+ checkbox_success = verify_recaptcha unless success
291
+ if success || checkbox_success
292
+ # Perform action
293
+ else
294
+ if !success
295
+ @show_checkbox_recaptcha = true
296
+ end
297
+ render 'new'
298
+ end
299
+ end
300
+ ```
301
+
302
+ (You can also find this [example](demo/rails/app/controllers/v3_captchas_controller.rb) in the demo app.)
303
+
304
+ Another example:
305
+
306
+ ```erb
307
+ <%= form_for @user do |f| %>
308
+
309
+ <%= recaptcha_v3(action: 'registration') %>
310
+
311
+ <% end %>
312
+ ```
313
+
314
+ ```ruby
315
+ # app/controllers/users_controller.rb
316
+ def create
317
+ @user = User.new(params[:user].permit(:name))
318
+ recaptcha_valid = verify_recaptcha(model: @user, action: 'registration')
319
+ if recaptcha_valid
320
+ if @user.save
321
+ redirect_to @user
322
+ else
323
+ render 'new'
324
+ end
325
+ else
326
+ # Score is below threshold, so user may be a bot. Show a challenge, require multi-factor
327
+ # authentication, or do something else.
328
+ render 'new'
329
+ end
330
+ end
331
+ ```
332
+
333
+
334
+ ### `recaptcha_v3`
335
+
336
+ Adds an inline script tag that calls `grecaptcha.execute` for the given `site_key` and `action` and
337
+ calls the `callback` with the resulting response token. You need to verify this token with
338
+ [`verify_recaptcha`](#verify_recaptcha-use-with-v3) in your controller in order to get the
339
+ [score](https://developers.google.com/recaptcha/docs/v3#score).
340
+
341
+ By default, this inserts a hidden `<input type="hidden" class="g-recaptcha-response">` tag. The
342
+ value of this input will automatically be set to the response token (by the default callback
343
+ function). This lets you include `recaptcha_v3` within a `<form>` tag and have it automatically
344
+ submit the token as part of the form submission.
345
+
346
+ Note: reCAPTCHA actually already adds its own hidden tag, like `<textarea
347
+ id="g-recaptcha-response-data-100000" name="g-recaptcha-response-data" class="g-recaptcha-response">`,
348
+ immediately ater the reCAPTCHA badge in the bottom right of the page — but since it is not inside of
349
+ any `<form>` element, and since it already passes the token to the callback, this hidden `textarea`
350
+ isn't helpful to us.
351
+
352
+ If you need to submit the response token to the server in a different way than via a regular form
353
+ submit, such as via [Ajax](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) or [`fetch`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API),
354
+ then you can either:
355
+ 1. just extract the token out of the hidden `<input>` or `<textarea>` (both of which will have a
356
+ predictable name/id), like `document.getElementById('g-recaptcha-response-data-my-action').value`, or
357
+ 2. write and specify a custom `callback` function. You may also want to pass `element: false` if you
358
+ don't have a use for the hidden input element.
359
+
360
+ Note that you cannot submit/verify the same response token more than once or you will get a
361
+ `timeout-or-duplicate` error code. If you need reset the captcha and generate a new response token,
362
+ then you need to call `grecaptcha.execute(…)` again. This helper provides a JavaScript method (for
363
+ each action) named `executeRecaptchaFor{action}` to make this easier. That is the same method that
364
+ is invoked immediately. It simply calls `grecaptcha.execute` again and then calls the `callback`
365
+ function with the response token.
366
+
367
+ You will also get a `timeout-or-duplicate` error if too much time has passed between getting the
368
+ response token and verifying it. This can easily happen with large forms that take the user a couple
369
+ minutes to complete. Unlike v2, where you can use the `expired-callback` to be notified when the
370
+ response expries, v3 appears to provide no such callback. See also
371
+ [1](https://github.com/google/recaptcha/issues/281) and
372
+ [2](https://stackoverflow.com/questions/54437745/recaptcha-v3-how-to-deal-with-expired-token-after-idle).
373
+
374
+ To deal with this, it is recommended to call the "execute" in your form's submit handler (or
375
+ immediately before sending to the server to verify if not using a form) rather than using the
376
+ response token that gets generated when the page first loads. The `executeRecaptchaFor{action}`
377
+ function mentioned above can be used if you want it to invoke a callback, or the
378
+ `executeRecaptchaFor{action}Async` variant if you want a `Promise` that you can `await`. See
379
+ [demo/rails/app/views/v3_captchas/index.html.erb](demo/rails/app/views/v3_captchas/index.html.erb)
380
+ for an example of this.
381
+
382
+ This helper is similar to the [`recaptcha_tags`](#recaptcha_tags)/[`invisible_recaptcha_tags`](#invisible_recaptcha_tags) helpers
383
+ but only accepts the following options:
384
+
385
+ | Option | Description |
386
+ |---------------------|-------------|
387
+ | `:site_key` | Override site API key |
388
+ | `:action` | The name of the [reCAPTCHA action](https://developers.google.com/recaptcha/docs/v3#actions). Actions may only contain alphanumeric characters and slashes, and must not be user-specific. |
389
+ | `:nonce` | Optional. Sets nonce attribute for script. Can be generated via `SecureRandom.base64(32)`. (default: `nil`) |
390
+ | `:callback` | Name of callback function to call with the token. When `element` is `:input`, this defaults to a function named `setInputWithRecaptchaResponseTokenFor#{sanitize_action(action)}` that sets the value of the hidden input to the token. |
391
+ | `:id` | Specify a unique `id` attribute for the `<input>` element if using `element: :input`. (default: `"g-recaptcha-response-data-"` + `action`) |
392
+ | `:name` | Specify a unique `name` attribute for the `<input>` element if using `element: :input`. (default: `g-recaptcha-response-data[action]`) |
393
+ | `:script` | Same as setting both `:inline_script` and `:external_script`. (default: `true`). |
394
+ | `:inline_script` | If `true`, adds an inline script tag that calls `grecaptcha.execute` for the given `site_key` and `action` and calls the `callback` with the resulting response token. Pass `false` if you want to handle calling `grecaptcha.execute` yourself. (default: `true`) |
395
+ | `:element` | The element to render, if any (default: `:input`)<br/>`:input`: Renders a hidden `<input type="hidden">` tag. The value of this will be set to the response token by the default `setInputWithRecaptchaResponseTokenFor{action}` callback.<br/>`false`: Doesn't render any tag. You'll have to add a custom callback that does something with the token. |
396
+ | `:turbolinks` | If `true`, calls the js function which executes reCAPTCHA after all the dependencies have been loaded. This cannot be used with the js param `:onload`. This makes reCAPTCHAv3 usable with turbolinks. |
397
+
398
+ [JavaScript resource (api.js) parameters](https://developers.google.com/recaptcha/docs/invisible#js_param):
399
+
400
+ | Option | Description |
401
+ |---------------------|-------------|
402
+ | `:onload` | Optional. The name of your callback function to be executed once all the dependencies have loaded. (See [explicit rendering](https://developers.google.com/recaptcha/docs/display#explicit_render))|
403
+ | `:external_script` | Set to `false` to avoid including a script tag for the external `api.js` resource. Useful when including multiple `recaptcha_tags` on the same page.
404
+ | `:script_async` | Set to `true` to load the external `api.js` resource asynchronously. (default: `false`) |
405
+ | `:script_defer` | Set to `true` to defer loading of external `api.js` until HTML documen has been parsed. (default: `false`) |
406
+
407
+ If using `element: :input`, any unrecognized options will be added as attributes on the generated
408
+ `<input>` element.
409
+
410
+ ### `verify_recaptcha` (use with v3)
411
+
412
+ This works the same as for v2, except that you may pass an `action` and `minimum_score` if you wish
413
+ to validate that the action matches or that the score is above the given threshold, respectively.
414
+
415
+ ```ruby
416
+ result = verify_recaptcha(action: 'action/name')
417
+ ```
418
+
419
+ | Option | Description |
420
+ |------------------|-------------|
421
+ | `:action` | The name of the [reCAPTCHA action](https://developers.google.com/recaptcha/docs/v3#actions) that we are verifying. Set to `false` or `nil` to skip verifying that the action matches.
422
+ | `:minimum_score` | Provide a threshold to meet or exceed. Threshold should be a float between 0 and 1 which will be tested as `score >= minimum_score`. (Default: `nil`) |
423
+
424
+ ### Multiple actions on the same page
425
+
426
+ According to https://developers.google.com/recaptcha/docs/v3#placement,
427
+
428
+ > Note: You can execute reCAPTCHA as many times as you'd like with different actions on the same page.
429
+
430
+ You will need to verify each action individually with separate call to `verify_recaptcha`.
431
+
432
+ ```ruby
433
+ result_a = verify_recaptcha(action: 'a')
434
+ result_b = verify_recaptcha(action: 'b')
435
+ ```
436
+
437
+ Because the response tokens for multiple actions may be submitted together in the same request, they
438
+ are passed as a hash under `params['g-recaptcha-response-data']` with the action as the key.
439
+
440
+ It is recommended to pass `external_script: false` on all but one of the calls to
441
+ `recaptcha` since you only need to include the script tag once for a given `site_key`.
442
+
443
+ ## `recaptcha_reply`
444
+
445
+ After `verify_recaptcha` has been called, you can call `recaptcha_reply` to get the raw reply from recaptcha. This can allow you to get the exact score returned by recaptcha should you need it.
446
+
447
+ ```ruby
448
+ if verify_recaptcha(action: 'login')
449
+ redirect_to @user
450
+ else
451
+ score = recaptcha_reply['score']
452
+ Rails.logger.warn("User #{@user.id} was denied login because of a recaptcha score of #{score}")
453
+ render 'new'
454
+ end
455
+ ```
456
+
457
+ `recaptcha_reply` will return `nil` if the the reply was not yet fetched.
458
+
459
+ ## I18n support
460
+
461
+ reCAPTCHA supports the I18n gem (it comes with English translations)
462
+ To override or add new languages, add to `config/locales/*.yml`
463
+
464
+ ```yaml
465
+ # config/locales/en.yml
466
+ en:
467
+ recaptcha:
468
+ errors:
469
+ verification_failed: 'reCAPTCHA was incorrect, please try again.'
470
+ recaptcha_unreachable: 'reCAPTCHA verification server error, please try again.'
471
+ ```
472
+
473
+ ## Testing
474
+
475
+ By default, reCAPTCHA is skipped in "test" and "cucumber" env. To enable it during test:
476
+
477
+ ```ruby
478
+ Recaptcha.configuration.skip_verify_env.delete("test")
479
+ ```
480
+
481
+ ## Alternative API key setup
482
+
483
+ ### Recaptcha.configure
484
+
485
+ ```ruby
486
+ # config/initializers/recaptcha.rb
487
+ Recaptcha.configure do |config|
488
+ config.site_key = '6Lc6BAAAAAAAAChqRbQZcn_yyyyyyyyyyyyyyyyy'
489
+ config.secret_key = '6Lc6BAAAAAAAAKN3DRm6VA_xxxxxxxxxxxxxxxxx'
490
+ # Uncomment the following line if you are using a proxy server:
491
+ # config.proxy = 'http://myproxy.com.au:8080'
492
+ end
493
+ ```
494
+
495
+ ### Recaptcha.with_configuration
496
+
497
+ For temporary overwrites (not thread safe).
498
+
499
+ ```ruby
500
+ Recaptcha.with_configuration(site_key: '12345') do
501
+ # Do stuff with the overwritten site_key.
502
+ end
503
+ ```
504
+
505
+ ### Per call
506
+
507
+ Pass in keys as options at runtime, for code base with multiple reCAPTCHA setups:
508
+
509
+ ```ruby
510
+ recaptcha_tags site_key: '6Lc6BAAAAAAAAChqRbQZcn_yyyyyyyyyyyyyyyyy'
511
+
512
+ # and
513
+
514
+ verify_recaptcha secret_key: '6Lc6BAAAAAAAAKN3DRm6VA_xxxxxxxxxxxxxxxxx'
515
+ ```
516
+
517
+ ## Misc
518
+ - Check out the [wiki](https://github.com/ambethia/recaptcha/wiki) and leave whatever you found valuable there.
519
+ - [Add multiple widgets to the same page](https://github.com/ambethia/recaptcha/wiki/Add-multiple-widgets-to-the-same-page)
520
+ - [Use Recaptcha with Devise](https://github.com/plataformatec/devise/wiki/How-To:-Use-Recaptcha-with-Devise)