diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..4d2d6fa --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module github.com/dpapathanasiou/go-recaptcha + +go 1.13 + +require github.com/pkg/errors v0.8.1 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..f29ab35 --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= diff --git a/recaptcha.go b/recaptcha.go index a3218a3..398b670 100644 --- a/recaptcha.go +++ b/recaptcha.go @@ -8,8 +8,8 @@ package recaptcha import ( "encoding/json" + "fmt" "io/ioutil" - "log" "net/http" "net/url" "time" @@ -28,44 +28,38 @@ const recaptchaServerName = "https://www.google.com/recaptcha/api/siteverify" var recaptchaPrivateKey string -// check uses the client ip address, the challenge code from the reCaptcha form, -// and the client's response input to that challenge to determine whether or not -// the client answered the reCaptcha input question correctly. -// It returns a boolean value indicating whether or not the client answered correctly. -func check(remoteip, response string) (r RecaptchaResponse, err error) { +// check will construct the request to the verification API, send it, and return the result. +func check(remoteip, response string) (RecaptchaResponse, error) { + var r RecaptchaResponse resp, err := http.PostForm(recaptchaServerName, url.Values{"secret": {recaptchaPrivateKey}, "remoteip": {remoteip}, "response": {response}}) if err != nil { - log.Printf("Post error: %s\n", err) - return + return r, fmt.Errorf("post error: %w", err) } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { - log.Println("Read error: could not read body: %s", err) - return + return r, fmt.Errorf("read error: could not read body: %w", err) } err = json.Unmarshal(body, &r) if err != nil { - log.Println("Read error: got invalid JSON: %s", err) - return + return r, fmt.Errorf("read error: JSON unmarshal error: %w", err) } - return + return r, nil } -// Confirm is the public interface function. -// It calls check, which the client ip address, the challenge code from the reCaptcha form, -// and the client's response input to that challenge to determine whether or not -// the client answered the reCaptcha input question correctly. -// It returns a boolean value indicating whether or not the client answered correctly. +// Confirm is the public interface function that validates the reCAPTCHA token. +// It accepts the client ip address and the token returned to the client after completing the challenge. +// It returns a boolean value indicating whether or not the client token is authentic, meaning the challenge +// was answered correctly. func Confirm(remoteip, response string) (result bool, err error) { resp, err := check(remoteip, response) result = resp.Success return } -// Init allows the webserver or code evaluating the reCaptcha form input to set the -// reCaptcha private key (string) value, which will be different for every domain. +// Init allows the webserver or code evaluating the reCAPTCHA token input to set the +// reCAPTCHA private key (string) value, which will be different for every domain. func Init(key string) { recaptchaPrivateKey = key }