-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrecaptcha.go
76 lines (60 loc) · 1.66 KB
/
recaptcha.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package recaptcha
import (
"encoding/json"
"io/ioutil"
"net/http"
"net/url"
)
var postUrl = "https://www.google.com/recaptcha/api/siteverify"
// Recaptcha struct stores the recaptcha configuration as well as the errors received
// from the Verify function.
type Recaptcha struct {
httpClient *http.Client
secret string
errors []string
}
type verifyResponse struct {
Success bool
ErrorCodes []string `json:"error-codes"`
}
func HTTPClient(c *http.Client) func(*Recaptcha) {
return func(r *Recaptcha) {
r.httpClient = c
}
}
// New returns a new Recaptcha struct using specified secret and any additional options.
// Default timeout is 30 seconds.
func New(secret string, options ...func(*Recaptcha)) *Recaptcha {
r := &Recaptcha{secret: secret}
for _, option := range options {
option(r)
}
if r.httpClient == nil {
r.httpClient = http.DefaultClient
}
return r
}
// Verify the recaptcha response, will return true or false. Any errors received will be
// stored in recaptcha struct.
func (r *Recaptcha) Verify(ipAddress string, response string) (bool, error) {
r.errors = nil
resp, err := r.httpClient.PostForm(postUrl, url.Values{"secret": {r.secret}, "response": {response}, "remoteip": {ipAddress}})
if err != nil {
return false, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return false, err
}
vr := new(verifyResponse)
if err := json.Unmarshal(body, &vr); err != nil {
return false, err
}
r.errors = vr.ErrorCodes
return vr.Success, nil
}
// GetErrors returns the error that occurred during last recaptcha attempt.
func (recaptcha *Recaptcha) GetErrors() []string {
return recaptcha.errors
}