Golang : reCAPTCHA example
For this tutorial we will explore how to implement reCAPTCHA with Golang. If you are running website with lots of user generated content, fighting spammers can be tedious and endless battle. To mitigate this problem, we can deploy reCAPTCHA service to minimize spammers activities on your website.
reCAPTCHA works by testing the visitor to see if they are a spambot or human. The tests deployed by reCAPTCHA are difficult for spambots to pass and will discourage human spammers from spamming your website repeatedly.
a sample of reCAPTCHA test
1. Register a reCAPTCHA account.
First, you need to register a reCAPTCHA account to create new site and secret keys for your website. Go to http://www.google.com/recaptcha/ to get the keys.
2. Bind reCAPTCHA to your form.
Next, we will bind the reCAPTCHA to a signup form. The code example below will be annotated to show where to place the reCAPTCHA codes.
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"time"
)
type JSONAPIResponse struct {
Success bool `json:"success"`
ChallengeTS time.Time `json:"challenge_ts"` // timestamp of the challenge load (ISO format yyyy-MM-dd'T'HH:mm:ssZZ)
Hostname string `json:"hostname"` // the hostname of the site where the reCAPTCHA was solved
ErrorCodes []int `json:"error-codes"` //optional
}
func RecaptchaForm(w http.ResponseWriter, r *http.Request) {
html := `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Golang reCAPTCHA Signup Form</title>
<script src='https://www.google.com/recaptcha/api.js'></script>
</head>
<body>
<h1>Golang reCAPTCHA Signup Form</h1>
<form method="POST" action="/signup">
Username : <input type="text" name="username">
<br>
Password : <input type="password" name="password">
<br>
<div class="g-recaptcha" data-sitekey="[REPLACE WITH YOUR DATA KEY]"></div>
<br>
<input type="submit" value="Submit">
</form>
</body>
</html>`
w.Write([]byte(html))
}
func Signup(w http.ResponseWriter, r *http.Request) {
if r.Method == "POST" {
fmt.Println("username : ", r.FormValue("username"))
fmt.Println("password : ", r.FormValue("password"))
response := r.FormValue("g-recaptcha-response")
fmt.Println("g-recaptcha-response : ", response)
// did we get a proper recaptcha response? if null, redirect back to sigup page
if response == "" {
// user press submit button without passing reCAPTCHA test
// abort
http.Redirect(w, r, "/", 301)
return // return control to stop execution, otherwise it will continue
}
// this is server side validation example
// it is optional, but no harm adding this on your signup verification process.
// if you are running this example on localhost
// get your own IP address from https://whatismyipaddress.com/
// and assign it to the variable ip
remoteip := "[REPLACE WITH YOUR IP ADDRESS IF ON LOCALHOST OR UNCOMMENT SPLITHOST BELOW]"
// get end user's IP address
//remoteip, _, _ := net.SplitHostPort(r.RemoteAddr)
fmt.Println("remote ip : ", remoteip)
// to verify if the recaptcha is REAL. we must send
// secret + response + remoteip(optional) to postURL
secret := "[REPLACE WITH YOUR SECRET KEY]"
postURL := "https://www.google.com/recaptcha/api/siteverify"
postStr := url.Values{"secret": {secret}, "response": {response}, "remoteip": {remoteip}}
responsePost, err := http.PostForm(postURL, postStr)
if err != nil {
fmt.Println(err)
return
}
defer responsePost.Body.Close()
body, err := ioutil.ReadAll(responsePost.Body)
if err != nil {
fmt.Println(err)
return
}
// this part is for server side verification
var APIResp JSONAPIResponse
json.Unmarshal(body, &APIResp)
fmt.Println(APIResp)
// see https://www.socketloop.com/tutorials/golang-output-or-print-out-json-stream-encoded-data
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(body))
//once everything is verified, you can proceed to save the user data into your database
}
}
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", RecaptchaForm)
mux.HandleFunc("/signup", Signup)
http.ListenAndServe(":8080", mux)
}
Run this program and point your browser to localhost:8080
or your own website configuration.
IF everything goes smoothly, you should see a prompt such as this
a signup form binded to reCAPTCHA
and upon successful verification, the JSON reply from reCAPTCHA API will appear on the web browser:
{
"success": true,
"challenge_ts": "2016-06-28T08:46:50Z",
"hostname": "localhost"
}
and on the terminal:
username : asd
password : asd
g-recaptcha-response : 03AHJVuuLBKWMkViN8MDY8qV7A9nLVdSlhVZEGkqq7CqynW1....
remote ip : 121.122.88.120
{true 2016-06-28 08:46:50 +0000 UTC localhost []}
References:
By Adam Ng
IF you gain some knowledge or the information here solved your programming problem. Please consider donating to the less fortunate or some charities that you like. Apart from donation, planting trees, volunteering or reducing your carbon footprint will be great too.
Advertisement
Tutorials
+7.3k Golang : Error reading timestamp with GORM or SQL driver
+9.7k Golang : Get login name from environment and prompt for password
+12.2k Swift : Convert (cast) Int or int32 value to CGFloat
+18k Golang : Logging with logrus
+13.8k Golang : How to convert a number to words
+16.2k Golang : Merge video(OpenCV) and audio(PortAudio) into a mp4 file
+21.7k Golang : Securing password with salt
+18.2k Unmarshal/Load CSV record into struct in Go
+5.4k Golang : Struct field tags and what is their purpose?
+8.6k Golang : io.Reader causing panic: runtime error: invalid memory address or nil pointer dereference
+38.6k Golang : How to iterate over a []string(array)
+6.7k CloudFlare : Another way to get visitor's real IP address