2021-01-28 15:38:58 +00:00
|
|
|
// From https://github.com/lukasaron/recaptcha
|
|
|
|
// BLS-3 Licensed
|
|
|
|
// Copyright (c) 2020, Lukas Aron
|
|
|
|
// Modified by Kubuxu
|
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
2023-03-29 19:24:07 +00:00
|
|
|
"io"
|
2021-01-28 15:38:58 +00:00
|
|
|
"net/http"
|
|
|
|
"net/url"
|
|
|
|
"os"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
// content type for communication with the verification server.
|
|
|
|
const (
|
|
|
|
contentType = "application/json"
|
|
|
|
)
|
|
|
|
|
|
|
|
// VerifyURL defines the endpoint which is called when a token needs to be verified.
|
|
|
|
var (
|
|
|
|
VerifyURL, _ = url.Parse("https://www.google.com/recaptcha/api/siteverify")
|
|
|
|
)
|
|
|
|
|
|
|
|
// Response defines the response format from the verification endpoint.
|
|
|
|
type Response struct {
|
|
|
|
Success bool `json:"success"` // status of the verification
|
|
|
|
TimeStamp time.Time `json:"challenge_ts"` // timestamp of the challenge load (ISO format)
|
|
|
|
HostName string `json:"hostname"` // the hostname of the site where the reCAPTCHA was solved
|
|
|
|
Score float64 `json:"score"` // the score for this request (0.0 - 1.0)
|
|
|
|
Action string `json:"action"` // the action name for this request
|
|
|
|
ErrorCodes []string `json:"error-codes"` // error codes
|
|
|
|
AndroidPackageName string `json:"apk_package_name"` // android related only
|
|
|
|
}
|
|
|
|
|
|
|
|
// VerifyToken function implements the basic logic of verification of ReCaptcha token that is usually created
|
|
|
|
// on the user site (front-end) and then sent to verify on the server side (back-end).
|
|
|
|
// To provide a successful verification process the secret key is required. Based on the security recommendations
|
|
|
|
// the key has to be passed as an environmental variable SECRET_KEY.
|
|
|
|
//
|
|
|
|
// Token parameter is required, however remoteIP is optional.
|
|
|
|
func VerifyToken(token, remoteIP string) (Response, error) {
|
|
|
|
resp := Response{}
|
|
|
|
if len(token) == 0 {
|
|
|
|
resp.ErrorCodes = []string{"no-token"}
|
|
|
|
return resp, nil
|
|
|
|
}
|
2021-01-28 17:07:37 +00:00
|
|
|
|
|
|
|
q := url.Values{}
|
2021-01-28 15:38:58 +00:00
|
|
|
q.Add("secret", os.Getenv("RECAPTCHA_SECRET_KEY"))
|
|
|
|
q.Add("response", token)
|
|
|
|
q.Add("remoteip", remoteIP)
|
|
|
|
|
2021-01-28 18:58:28 +00:00
|
|
|
var u *url.URL
|
|
|
|
{
|
|
|
|
verifyCopy := *VerifyURL
|
|
|
|
u = &verifyCopy
|
|
|
|
}
|
2021-01-28 17:07:37 +00:00
|
|
|
u.RawQuery = q.Encode()
|
|
|
|
r, err := http.Post(u.String(), contentType, nil)
|
2021-01-28 15:38:58 +00:00
|
|
|
if err != nil {
|
|
|
|
return resp, err
|
|
|
|
}
|
|
|
|
|
2023-03-29 19:24:07 +00:00
|
|
|
b, err := io.ReadAll(r.Body)
|
2021-01-28 15:38:58 +00:00
|
|
|
_ = r.Body.Close() // close immediately after reading finished
|
|
|
|
if err != nil {
|
|
|
|
return resp, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return resp, json.Unmarshal(b, &resp)
|
|
|
|
}
|