WIP
This commit is contained in:
90
recaptcha/recaptcha.go
Normal file
90
recaptcha/recaptcha.go
Normal file
@@ -0,0 +1,90 @@
|
||||
package recaptcha
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/securecookie"
|
||||
"github.com/play-with-docker/play-with-docker/config"
|
||||
"github.com/twinj/uuid"
|
||||
)
|
||||
|
||||
func GetGoogleRecaptchaSiteKey() string {
|
||||
key := os.Getenv("GOOGLE_RECAPTCHA_SITE_KEY")
|
||||
if key == "" {
|
||||
// This is a development default. The environment variable should always be set in production.
|
||||
key = "6LeY_QsUAAAAAOlpVw4MhoLEr50h-dM80oz6M2AX"
|
||||
}
|
||||
return key
|
||||
}
|
||||
func GetGoogleRecaptchaSiteSecret() string {
|
||||
key := os.Getenv("GOOGLE_RECAPTCHA_SITE_SECRET")
|
||||
if key == "" {
|
||||
// This is a development default. The environment variable should always be set in production.
|
||||
key = "6LeY_QsUAAAAAHIALCtm0GKfk-UhtXoyJKarnRV8"
|
||||
}
|
||||
|
||||
return key
|
||||
}
|
||||
|
||||
type recaptchaResponse struct {
|
||||
Success bool `json:"success"`
|
||||
}
|
||||
|
||||
var s = securecookie.New([]byte(config.HashKey), nil).MaxAge(int((1 * time.Hour).Seconds()))
|
||||
|
||||
func IsHuman(req *http.Request, rw http.ResponseWriter) bool {
|
||||
if os.Getenv("GOOGLE_RECAPTCHA_DISABLED") != "" {
|
||||
return true
|
||||
}
|
||||
|
||||
if cookie, _ := req.Cookie("session_id"); cookie != nil {
|
||||
var value string
|
||||
if err := s.Decode("session_id", cookie.Value, &value); err != nil {
|
||||
fmt.Println(err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
challenge := req.Form.Get("g-recaptcha-response")
|
||||
|
||||
// Of X-Forwarded-For exists, it means we are behind a loadbalancer and we should use the real IP address of the user
|
||||
ip := req.Header.Get("X-Forwarded-For")
|
||||
if ip == "" {
|
||||
// Use the standard remote IP address of the request
|
||||
|
||||
ip = req.RemoteAddr
|
||||
}
|
||||
|
||||
parts := strings.Split(ip, ":")
|
||||
|
||||
resp, postErr := http.PostForm("https://www.google.com/recaptcha/api/siteverify", url.Values{"secret": {GetGoogleRecaptchaSiteSecret()}, "response": {challenge}, "remoteip": {parts[0]}})
|
||||
if postErr != nil {
|
||||
log.Println(postErr)
|
||||
// If there is a problem to connect to google, assume the user is a human so we don't block real users because of technical issues
|
||||
return true
|
||||
}
|
||||
|
||||
var r recaptchaResponse
|
||||
json.NewDecoder(resp.Body).Decode(&r)
|
||||
|
||||
if !r.Success {
|
||||
return false
|
||||
}
|
||||
|
||||
encoded, _ := s.Encode("session_id", uuid.NewV4().String())
|
||||
http.SetCookie(rw, &http.Cookie{
|
||||
Name: "session_id",
|
||||
Value: encoded,
|
||||
Expires: time.Now().Add(1 * time.Hour),
|
||||
})
|
||||
|
||||
return true
|
||||
}
|
||||
Reference in New Issue
Block a user