A simple Elixir package for implementing reCAPTCHA in Elixir applications. Forked from samueljseay/recaptcha and bounceapp/recaptcha.
- Template functionality is now in a separate module:
Recaptcha.Template
. Please note: in future templating may move to a Phoenix specific package. verify
API has changed, see the code for documentation of the new API.
Most other questions about 2.x should be answered by looking over the documentation and the code. Please raise an issue if you have any problems with migrating.
- Now requires Elixir version 1.13 or later
- The reCATPCHA widget has been removed. If you need this widget we suggest you inline it in your project from the previous version of this library.
Add :recaptcha
to your mix.exs
dependencies:
defp deps do
[
{:recaptcha, github: "remoteoss/recaptcha"},
]
end
List :recaptcha
as an application dependency:
def application do
[
extra_applications: [:recaptcha]
]
end
Run mix do deps.get, compile
By default the public and private keys are loaded via the RECAPTCHA_PUBLIC_KEY
and RECAPTCHA_PRIVATE_KEY
environment variables.
config :recaptcha,
public_key: {:system, "RECAPTCHA_PUBLIC_KEY"},
secret: {:system, "RECAPTCHA_PRIVATE_KEY"}
By default reCaptcha
will use Jason
to decode JSON responses, this can be changed as such:
config :recaptcha, :json_library, Poison
Recaptcha provides the verify/2
method. Below is an example using a Phoenix controller action:
def create(conn, params) do
case Recaptcha.verify(params["g-recaptcha-response"]) do
{:ok, response} -> do_something
{:error, errors} -> handle_error
end
end
verify
method sends a POST
request to the reCAPTCHA API and returns 2 possible values:
{:ok, %Recaptcha.Response{challenge_ts: timestamp, hostname: host}}
-> The captcha is valid, see the documentation for more details.
{:error, errors}
-> errors
contains atomised versions of the errors returned by the API, See the error documentation for more details. Errors caused by timeouts in HTTPoison or Jason encoding are also returned as atoms. If the recaptcha request succeeds but the challenge is failed, a :challenge_failed
error is returned.
verify
method also accepts a keyword list as the third parameter with the following options:
Option | Action | Default |
---|---|---|
timeout |
Time to wait before timeout | 5000 (ms) |
secret |
Private key to send as a parameter of the API request | Private key from the config file |
remote_ip |
Optional. The user's IP address, used by reCaptcha | no default |
The recommended way to mock responses from recaptcha
is to create a module implementing a request_verification/2
function, and pass it to recaptcha's :http_client
config, for example:
defmodule RecaptchaMock do
def request_verification(query_string, _opts) do
# You can pattern-match against the secret and recaptcha response provided to `Recaptcha.verify/1` in the `query_string` in
# case you want different responses in your tests.
response =
cond do
String.contains?(query_string, "response=zero_score") ->
%{"success" => true, "score" => 0.0, "challenge_ts" => "timestamp", "hostname" => "localhost"}
true ->
%{"success" => true, "score" => 1.0, "challenge_ts" => "timestamp", "hostname" => "localhost"}
end
{:ok, response}
end
end
And then, on your config:
config :recaptcha, http_client: RecaptchaMock
This allows you to run tests without network, but you can still run automated tests against Recaptcha's servers by following Google's guide.
Check out CONTRIBUTING.md if you want to help.
Copyright (c) 2016 Samuel Seay
This library is released under the MIT License. See the LICENSE.md file for further details.