recaptcha 4.14.0 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9b5ffc9bf0c060fee8d77fd96405cfe4a4b9a023663a28ad81a908e674ad6674
4
- data.tar.gz: 958f628e01e816b2d27f7fccad2f0c7e14e701789093ee856316738b5b4810d6
3
+ metadata.gz: b146b489348963aec2bc4576903ff9d4f130fb65b7fe268558d4ce1430be0078
4
+ data.tar.gz: 63c8a898a6e1e207e3988105a8916954e959fb77dc762d77c03ebd6c76bd95f1
5
5
  SHA512:
6
- metadata.gz: f1f835a629b92c10e4250d89db0f8717a5a6907f631a97ef90c0989b2d97875c9cffd81559872d7c025dd86c0a53e301bdd4ee9c60d745070cf4bfce8c24049e
7
- data.tar.gz: 361b8d29ab4b9201faf4e6c87cc7bf35043915cebb4714b2c6f4424214476cef96dfe7c9707b8ffb63e7ea320dccf324ba2759b62c5344e48942647de718638e
6
+ metadata.gz: 3850b9716c496b63d25485ce9cf422a5610aeb5f348acbe6fd5bb0e20cd4834290890f6f8aa6927fe997085b19371f9414a57954176c2244f84e855d6f7ec9d0
7
+ data.tar.gz: 492f92ab871182c685f4fa098cea1bdc616ae377b2df376c7e24e3ae65739c02871d7dd7fe95ba89d5ded14445cd480904cd180437482d67d6d98cffbc2f224c
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## Next
2
+
3
+ ## 5.0.0
4
+ * Changed host to Recaptcha.net
5
+ * Add v3 API support
6
+ * Renamed `Recaptcha::ClientHelper` to `Recaptcha::Adapters::ViewMethods`
7
+ * Renamed `Recaptcha::Verify` to `Recaptcha::Adapters::ControllerMethods`
8
+
1
9
  ## 4.12.0 - 2018-08-30
2
10
  * add `input` option to `invisible_recaptcha_tags`'s `ui` setting
3
11
 
@@ -66,6 +74,11 @@
66
74
  * support disabling stoken
67
75
  * support Rails.env
68
76
 
77
+ ## 0.4.0 / 2015-03-22
78
+
79
+ * Add support for ReCaptcha v2 API
80
+ * V2 API requires `g-recaptcha-response` parameters; https://github.com/ambethia/recaptcha/pull/114
81
+
69
82
  ## 0.3.6 / 2012-01-07
70
83
 
71
84
  * Many documentation changes
data/README.md CHANGED
@@ -1,4 +1,5 @@
1
1
  # reCAPTCHA
2
+ [![Gem Version](https://badge.fury.io/rb/recaptcha.svg)](https://badge.fury.io/rb/recaptcha)
2
3
 
3
4
  Author: Jason L Perry (http://ambethia.com)<br/>
4
5
  Copyright: Copyright (c) 2007-2013 Jason L Perry<br/>
@@ -6,42 +7,62 @@ License: [MIT](http://creativecommons.org/licenses/MIT/)<br/>
6
7
  Info: https://github.com/ambethia/recaptcha<br/>
7
8
  Bugs: https://github.com/ambethia/recaptcha/issues<br/>
8
9
 
9
- This plugin adds helpers for the [reCAPTCHA API](https://www.google.com/recaptcha). In your
10
- views you can use the `recaptcha_tags` method to embed the needed javascript,
11
- and you can validate in your controllers with `verify_recaptcha` or `verify_recaptcha!`,
12
- which throws an error on failiure.
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.
13
14
 
14
- ## Rails Installation
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 |
15
26
 
16
- [obtain a reCAPTCHA API key](https://www.google.com/recaptcha/admin). Note: Use localhost or 127.0.0.1 in domain if using localhost:3000.
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."
17
30
 
18
- ```Ruby
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
19
36
  gem "recaptcha"
20
37
  ```
21
38
 
22
- Keep keys out of the code base with environment variables.<br/>
23
- Set in production and locally use [dotenv](https://github.com/bkeepers/dotenv), make sure to add it above recaptcha.
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/>
24
40
 
25
- Otherwise see [Alternative API key setup](#alternative-api-key-setup).
41
+ In development, you can use the [dotenv](https://github.com/bkeepers/dotenv) gem. (Make sure to add it above `gem 'recaptcha'`.)
26
42
 
27
- ```
28
- export RECAPTCHA_SITE_KEY = '6Lc6BAAAAAAAAChqRbQZcn_yyyyyyyyyyyyyyyyy'
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'
29
50
  export RECAPTCHA_SECRET_KEY = '6Lc6BAAAAAAAAKN3DRm6VA_xxxxxxxxxxxxxxxxx'
30
51
  ```
31
52
 
32
- Add `recaptcha_tags` to the forms you want to protect.
53
+ Add `recaptcha_tags` to the forms you want to protect:
33
54
 
34
- ```Erb
55
+ ```erb
35
56
  <%= form_for @foo do |f| %>
36
- # ... other tags
57
+ #
37
58
  <%= recaptcha_tags %>
38
- # ... other tags
59
+ #
39
60
  <% end %>
40
61
  ```
41
62
 
42
- And, add `verify_recaptcha` logic to each form action that you've protected.
63
+ Then, add `verify_recaptcha` logic to each form action that you've protected:
43
64
 
44
- ```Ruby
65
+ ```ruby
45
66
  # app/controllers/users_controller.rb
46
67
  @user = User.new(params[:user].permit(:name))
47
68
  if verify_recaptcha(model: @user) && @user.save
@@ -57,63 +78,123 @@ See [sinatra demo](/demo/sinatra) for details.
57
78
 
58
79
  - add `gem 'recaptcha'` to `Gemfile`
59
80
  - set env variables
60
- - `include Recaptcha::ClientHelper` where you need `recaptcha_tags`
61
- - `include Recaptcha::Verify` where you need `verify_recaptcha`
81
+ - `include Recaptcha::Adapters::ViewMethods` where you need `recaptcha_tags`
82
+ - `include Recaptcha::Adapters::ControllerMethods` where you need `verify_recaptcha`
62
83
 
63
- ## recaptcha_tags
64
84
 
65
- Some of the options available:
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`)|
66
106
 
67
- | Option | Description |
68
- |-------------------|-------------|
69
- | :noscript | Include <noscript> content (default `true`)|
70
- | :theme | Specify the theme to be used per the API. Available options: `dark` and `light`. (default `light`)|
71
- | :ajax | Render the dynamic AJAX captcha per the API. (default `false`)|
72
- | :site_key | Override site API key |
73
- | :error | Override the error code returned from the reCAPTCHA API (default `nil`)|
74
- | :size | Specify a size (default `nil`)|
75
- | :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)) |
76
- | :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))|
77
- | :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))|
78
- | :nonce | Optional. Sets nonce attribute for script. Can be generated via `SecureRandom.base64(32)`. (default `nil`)|
79
- | :id | Specify an html id attribute (default `nil`)|
80
- | :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`)|
81
- | :callback | Optional. Name of success callback function, executed when the user submits a successful response |
82
- | :expired_callback | Optional. Name of expiration callback function, executed when the reCAPTCHA response expires and the user needs to re-verify. |
83
- | :error_callback | Optional. Name of error callback function, executed when reCAPTCHA encounters an error (e.g. network connectivity) |
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.
84
120
 
85
121
  You can also override the html attributes for the sizes of the generated `textarea` and `iframe`
86
- elements, if CSS isn't your thing. Inspect the source of `recaptcha_tags` to see these options.
122
+ elements, if CSS isn't your thing. Inspect the [source of `recaptcha_tags`](https://github.com/ambethia/recaptcha/blob/master/lib/recaptcha/client_helper.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`
87
130
 
88
- ## verify_recaptcha
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).
89
133
 
90
- This method returns `true` or `false` after processing the parameters from the reCAPTCHA widget. Why
91
- isn't this a model validation? Because that violates MVC. You can use it like this, or how ever you
92
- like. Passing in the ActiveRecord object is optional, if you do--and the captcha fails to verify--an
93
- error will be added to the object for you to use.
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.
94
140
 
95
141
  Some of the options available:
96
142
 
97
- | Option | Description |
98
- |--------------|-------------|
99
- | :model | Model to set errors.
100
- | :attribute | Model attribute to receive errors. (default :base)
101
- | :message | Custom error message.
102
- | :secret_key | Override secret API key.
103
- | :timeout | The number of seconds to wait for reCAPTCHA servers before give up. (default `3`)
104
- | :response | Custom response parameter. (default: params['g-recaptcha-response'])
105
- | :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`)
106
- | :env | Current environment. The request to verify will be skipped if the environment is specified in configuration under `skip_verify_env`
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']`)
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".
107
158
 
108
- ## invisible_recaptcha_tags
159
+ For more information, refer to: [Invisible reCAPTCHA](https://developers.google.com/recaptcha/docs/invisible).
109
160
 
110
- Make sure to read [Invisible reCAPTCHA](https://developers.google.com/recaptcha/docs/invisible).
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`) |
111
192
 
112
193
  ### With a single form on a page
113
194
 
114
195
  1. The `invisible_recaptcha_tags` generates a submit button for you.
115
196
 
116
- ```Erb
197
+ ```erb
117
198
  <%= form_for @foo do |f| %>
118
199
  # ... other tags
119
200
  <%= invisible_recaptcha_tags text: 'Submit form' %>
@@ -127,14 +208,14 @@ Then, add `verify_recaptcha` to your controller as seen [above](#rails-installat
127
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.
128
209
  2. The `invisible_recaptcha_tags` generates a submit button for you.
129
210
 
130
- ```Erb
211
+ ```erb
131
212
  <%= form_for @foo, html: {id: 'invisible-recaptcha-form'} do |f| %>
132
213
  # ... other tags
133
214
  <%= invisible_recaptcha_tags callback: 'submitInvisibleRecaptchaForm', text: 'Submit form' %>
134
215
  <% end %>
135
216
  ```
136
217
 
137
- ```Javascript
218
+ ```javascript
138
219
  // app/assets/javascripts/application.js
139
220
  var submitInvisibleRecaptchaForm = function () {
140
221
  document.getElementById("invisible-recaptcha-form").submit();
@@ -147,7 +228,7 @@ Finally, add `verify_recaptcha` to your controller as seen [above](#rails-instal
147
228
 
148
229
  1. Specify `ui` option
149
230
 
150
- ```Erb
231
+ ```erb
151
232
  <%= form_for @foo, html: {id: 'invisible-recaptcha-form'} do |f| %>
152
233
  # ... other tags
153
234
  <button type="button" id="submit-btn">
@@ -157,7 +238,7 @@ Finally, add `verify_recaptcha` to your controller as seen [above](#rails-instal
157
238
  <% end %>
158
239
  ```
159
240
 
160
- ```Javascript
241
+ ```javascript
161
242
  // app/assets/javascripts/application.js
162
243
  document.getElementById('submit-btn').addEventListener('click', function (e) {
163
244
  // do some validation
@@ -172,6 +253,189 @@ var submitInvisibleRecaptchaForm = function () {
172
253
  };
173
254
  ```
174
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 if it is below the threshold:
274
+
275
+ ```erb
276
+
277
+ <% if @show_checkbox_recaptcha %>
278
+ <%= recaptcha_tags %>
279
+ <% else %>
280
+ <%= recaptcha_v3(action: 'login') %>
281
+ <% end %>
282
+
283
+ ```
284
+
285
+ ```ruby
286
+ # app/controllers/sessions_controller.rb
287
+ def create
288
+ success = verify_recaptcha(action: 'login', minimum_score: 0.5)
289
+ checkbox_success = verify_recaptcha_tags unless success
290
+ if success || checkbox_success
291
+ # Perform action
292
+ else
293
+ if !success
294
+ @show_checkbox_recaptcha = true
295
+ end
296
+ render 'new'
297
+ end
298
+ end
299
+ ```
300
+
301
+ Another example:
302
+
303
+ ```erb
304
+ <%= form_for @user do |f| %>
305
+
306
+ <%= recaptcha_v3(action: 'registration') %>
307
+
308
+ <% end %>
309
+ ```
310
+
311
+ ```ruby
312
+ # app/controllers/users_controller.rb
313
+ def create
314
+ @user = User.new(params[:user].permit(:name))
315
+ recaptcha_valid = verify_recaptcha(model: @user, action: 'registration')
316
+ if recaptcha_valid
317
+ if @user.save
318
+ redirect_to @user
319
+ else
320
+ render 'new'
321
+ end
322
+ else
323
+ # Score is below threshold, so user may be a bot. Show a challenge, require multi-factor
324
+ # authentication, or do something else.
325
+ render 'new'
326
+ end
327
+ end
328
+ ```
329
+
330
+
331
+ ### `recaptcha_v3`
332
+
333
+ Adds an inline script tag that calls `grecaptcha.execute` for the given `site_key` and `action` and
334
+ calls the `callback` with the resulting response token. You need to verify this token with
335
+ [`verify_recaptcha`](#verify_recaptcha_use_with_v3) in your controller in order to get the
336
+ [score](https://developers.google.com/recaptcha/docs/v3#score).
337
+
338
+ By default, this inserts a hidden `<input type="hidden" class="g-recaptcha-response">` tag. The
339
+ value of this input will automatically be set to the response token (by the default callback
340
+ function). This lets you include `recaptcha_v3` within a `<form>` tag and have it automatically
341
+ submit the token as part of the form submission.
342
+
343
+ Note: reCAPTCHA actually already adds its own hidden tag, like `<textarea
344
+ id="g-recaptcha-response-100000" name="g-recaptcha-response" class="g-recaptcha-response">`,
345
+ immediately ater the reCAPTCHA badge in the bottom right of the page — but since it is not inside of
346
+ any `<form>` element, and since it already passes the token to the callback, this hidden `textarea`
347
+ isn't helpful to us.
348
+
349
+ If you need to submit the response token to the server in a different way than via a regular form
350
+ 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),
351
+ then you can either:
352
+ 1. just extract the token out of the hidden `<input>` or `<textarea>` (both of which will have a
353
+ predictable name/id), like `document.getElementById('g-recaptcha-response-my-action').value`, or
354
+ 2. write and specify a custom `callback` function. You may also want to pass `element: false` if you
355
+ don't have a use for the hidden input element.
356
+
357
+ Note that you cannot submit/verify the same response token more than once or you will get a
358
+ `timeout-or-duplicate` error code. If you need reset the captcha and generate a new response token,
359
+ then you need to call `grecaptcha.execute(…)` again. This helper provides a JavaScript method (for
360
+ each action) named `executeRecaptchaFor{action}` to make this easier. That is the same method that
361
+ is invoked immediately. It simply calls `grecaptcha.execute` again and then calls the `callback`
362
+ function with the response token.
363
+
364
+ You will also get a `timeout-or-duplicate` error if too much time has passed between getting the
365
+ response token and verifying it. This can easily happen with large forms that take the user a couple
366
+ minutes to complete. Unlike v2, where you can use the `expired-callback` to be notified when the
367
+ response expries, v3 appears to provide no such callback. See also
368
+ [1](https://github.com/google/recaptcha/issues/281) and
369
+ [2](https://stackoverflow.com/questions/54437745/recaptcha-v3-how-to-deal-with-expired-token-after-idle).
370
+
371
+ To deal with this, it is recommended to call the "execute" in your form's submit handler (or
372
+ immediately before sending to the server to verify if not using a form) rather than using the
373
+ response token that gets generated when the page first loads. The `executeRecaptchaFor{action}`
374
+ function mentioned above can be used if you want it to invoke a callback, or the
375
+ `executeRecaptchaFor{action}Async` variant if you want a `Promise` that you can `await`. See
376
+ [demo/rails/app/views/v3_captchas/index.html.erb](demo/rails/app/views/v3_captchas/index.html.erb)
377
+ for an example of this.
378
+
379
+ This helper is similar to the [`recaptcha_tags`](#recaptcha_tags)/[`invisible_recaptcha_tags`](#invisible_recaptcha_tags) helpers
380
+ but only accepts the following options:
381
+
382
+ | Option | Description |
383
+ |---------------------|-------------|
384
+ | `:site_key` | Override site API key |
385
+ | `: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. |
386
+ | `:nonce` | Optional. Sets nonce attribute for script. Can be generated via `SecureRandom.base64(32)`. (default: `nil`) |
387
+ | `: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. |
388
+ | `:id` | Specify a unique `id` attribute for the `<input>` element if using `element: :input`. (default: `"g-recaptcha-response-"` + `action`) |
389
+ | `:name` | Specify a unique `name` attribute for the `<input>` element if using `element: :input`. (default: `g-recaptcha-response[action]`) |
390
+ | `:script` | Same as setting both `:inline_script` and `:external_script`. (default: `true`). |
391
+ | `: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`) |
392
+ | `: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. |
393
+
394
+ [JavaScript resource (api.js) parameters](https://developers.google.com/recaptcha/docs/invisible#js_param):
395
+
396
+ | Option | Description |
397
+ |---------------------|-------------|
398
+ | `: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))|
399
+ | `: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.
400
+ | `:script_async` | Set to `true` to load the external `api.js` resource asynchronously. (default: `false`) |
401
+ | `:script_defer` | Set to `true` to defer loading of external `api.js` until HTML documen has been parsed. (default: `false`) |
402
+
403
+ If using `element: :input`, any unrecognized options will be added as attributes on the generated
404
+ `<input>` element.
405
+
406
+ ### `verify_recaptcha` (use with v3)
407
+
408
+ This works the same as for v2, except that you may pass an `action` and `minimum_score` if you wish
409
+ to validate that the action matches or that the score is above the given threshold, respectively.
410
+
411
+ ```ruby
412
+ result = verify_recaptcha(action: 'action/name')
413
+ ```
414
+
415
+ | Option | Description |
416
+ |------------------|-------------|
417
+ | `: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.
418
+ | `: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`) |
419
+
420
+ ### Multiple actions on the same page
421
+
422
+ According to https://developers.google.com/recaptcha/docs/v3#placement,
423
+
424
+ > Note: You can execute reCAPTCHA as many times as you'd like with different actions on the same page.
425
+
426
+ You will need to verify each action individually with separate call to `verify_recaptcha`.
427
+
428
+ ```ruby
429
+ result_a = verify_recaptcha(action: 'a')
430
+ result_b = verify_recaptcha(action: 'b')
431
+ ```
432
+
433
+ Because the response tokens for multiple actions may be submitted together in the same request, they
434
+ are passed as a hash under `params['g-recaptcha-response']` with the action as the key.
435
+
436
+ It is recommended to pass `external_script: false` on all but one of the calls to
437
+ `recaptcha` since you only need to include the script tag once for a given `site_key`.
438
+
175
439
  ## I18n support
176
440
  reCAPTCHA passes two types of error explanation to a linked model. It will use the I18n gem
177
441
  to translate the default error message if I18n is available. To customize the messages to your locale,
@@ -182,7 +446,7 @@ add these keys to your I18n backend:
182
446
 
183
447
  Also you can translate API response errors to human friendly by adding translations to the locale (`config/locales/en.yml`):
184
448
 
185
- ```Yaml
449
+ ```yaml
186
450
  en:
187
451
  recaptcha:
188
452
  errors:
@@ -193,7 +457,7 @@ en:
193
457
 
194
458
  By default, reCAPTCHA is skipped in "test" and "cucumber" env. To enable it during test:
195
459
 
196
- ```Ruby
460
+ ```ruby
197
461
  Recaptcha.configuration.skip_verify_env.delete("test")
198
462
  ```
199
463
 
@@ -201,7 +465,7 @@ Recaptcha.configuration.skip_verify_env.delete("test")
201
465
 
202
466
  ### Recaptcha.configure
203
467
 
204
- ```Ruby
468
+ ```ruby
205
469
  # config/initializers/recaptcha.rb
206
470
  Recaptcha.configure do |config|
207
471
  config.site_key = '6Lc6BAAAAAAAAChqRbQZcn_yyyyyyyyyyyyyyyyy'
@@ -215,7 +479,7 @@ end
215
479
 
216
480
  For temporary overwrites (not thread safe).
217
481
 
218
- ```Ruby
482
+ ```ruby
219
483
  Recaptcha.with_configuration(site_key: '12345') do
220
484
  # Do stuff with the overwritten site_key.
221
485
  end
@@ -225,7 +489,7 @@ end
225
489
 
226
490
  Pass in keys as options at runtime, for code base with multiple reCAPTCHA setups:
227
491
 
228
- ```Ruby
492
+ ```ruby
229
493
  recaptcha_tags site_key: '6Lc6BAAAAAAAAChqRbQZcn_yyyyyyyyyyyyyyyyy'
230
494
 
231
495
  # and
@@ -237,3 +501,4 @@ verify_recaptcha secret_key: '6Lc6BAAAAAAAAKN3DRm6VA_xxxxxxxxxxxxxxxxx'
237
501
  - Check out the [wiki](https://github.com/ambethia/recaptcha/wiki) and leave whatever you found valuable there.
238
502
  - [Add multiple widgets to the same page](https://github.com/ambethia/recaptcha/wiki/Add-multiple-widgets-to-the-same-page)
239
503
  - [Use Recaptcha with Devise](https://github.com/plataformatec/devise/wiki/How-To:-Use-Recaptcha-with-Devise)
504
+