Bots are bad and annoying, I hate them. I know you do too, that’s why you are here. This Google Recaptcha V3 in GoLang Tutorial will explain and walk you through how you can integrate the Google Recaptcha(V3) in websites build in Golang and get rid of Bots and spammers.
The request will be validated by Google using Captcha Response and then Google will return the authenticity score of Request. Based on the score you can decide if you want to grant access to the request. In this tutorial, we will implement the front end and backend both. If you know the entire drill and you here just for the code click the below Download button and download the code.
1. Obtaining the Google Captcha Site Key and Secret Key
First, you will need Site key and Secret Key from google Captcha dashboard. Using Site key and Secret Key you can integrate the Google Captcha in your Website. To obtain the Site key and Secret Key you have to create a Site and fill the below form,
After filling the entire form as shown in the above image, click on the submit button. After submitting the form you will get your Site Key and Secret Key as shown in the below screen,
Also read,Facebook Login in GoLang Tutorial
2. Understanding the project structure
Here we will give a very little bit of styling to our web application just to make it look presentable. And we won’t be using any frontend libraries or frameworks, for the sake of simplicity.
Since we are using plain Javascript and there is not much on the client-side to understand, hence we will focus on the Backend part only. Inside theviewsfolder, we will write down the MARKUP.
Apart from the public folder we have only go files, let’s understand the purpose of each file why we need them.
db.go:The file will have code to connect the Redis database.
routes-handlers.go:This file will have the actual logic of the application. Here we will write code to store the Hash Key with the actual URL and the Redirection Logic will be handled here only.
routes.go:As the name suggests, this file will contain the endpoints that we will define in this application.
structs.go:In this file, we will write all the structs that will be used in this application.
server.go:To create the Golang server we will use server.go file.
3. Creating a GoLang Server
Create aserver.goin the root of the project, which will be our entry point for the project. Here we will make a connection with the MongoDB database and we will define our application routes.
=>Inside themain()function, First we are printing some information.
=>In the next line, we will createroutevariable, which will hold Route instance.
=>ThenAddApproutes()function register application routes.
=>And at the end, usinghttp.ListenAndServe()we will start our GO server.
server.go:
package main
import (
"log"
"net/http"
"github.com/gorilla/mux"
"github.com/joho/godotenv"
)
func main() {
godotenv.Load()
log.Println("Server will start at http://localhost:8000/")
route := mux.NewRouter()
AddApproutes(route)
log.Fatal(http.ListenAndServe(":8000", route))
}
4. Adding GoLang Structs
Create astructs.goin the root of the project, Here we will register all structs used in this application. The reason for creating a separate file is that your code will look more clear and it will become very easy to read.
structs.go:
package main
// ErrorResponse is struct for sending error message with code.
type ErrorResponse struct {
Code int
Message string
}
// SuccessResponse is struct for sending error message with code.
type SuccessResponse struct {
Code int
Message string
Response interface{}
}
// StoreMessageRequest is struct for requests of /storeMessage API
type StoreMessageRequest struct {
Message string `json:"message"`
Token string `json:"token"`
}
// CaptchaPayloadRequest is struct for payload of verify captcha API
type CaptchaPayloadRequest struct {
secret string
response string
}
5. Adding GoLang routes in the application
Create aroutes.goin the root of the project, Here we will register application routes. Here we will usegorilla/muxpackage to register routes.
=>ThenAddApproutes()function will register all the routes in the application. Here we have only one route to add which will be used by the FrontEnd javascript.
=>/RenderHomeAPI will render the Form to fill and after submission, we will call the /storeMessage API.
=>/storeMessageAPI will call the Google API to verify the Captcha.
routes.go:
package main
import (
"log"
"github.com/gorilla/mux"
)
// AddApproutes will add the routes for the application
func AddApproutes(route *mux.Router) {
log.Println("Loadeding Routes...")
route.HandleFunc("/", RenderHome)
route.HandleFunc("/storeMessage", StoreMessage).Methods("POST")
log.Println("Routes are Loaded.")
}
6. Rendering and Displaying the frontend
Now as you know the /RenderHomeAPI will render the template. This template will display a very simple form to fill the text message and there will be a submit button. In this section, we will see how that is implemented,
Now create a routes-handlers.go and write down the below code,
routes-handlers.go:
package main
import (
"net/http"
)
// RenderHome Rendering the Home Page
func RenderHome(response http.ResponseWriter, request *http.Request) {
http.ServeFile(response, request, "views/index.html")
}Explanation:
- The
RenderHome()function will render theindex.htmlfile which is stored inside the/viewsfolder. - In this function, we make use of the
http.ServeFilemethod of HTTP package to render the HTML file.
Now let’s write the template file, which will display a very simple HTML form. In this form, we will have One Textbox and a Submit button and upon click that button we will call an API to verify the Captcha Request.
=> After running the below markup you will notice, on the right end corner a Google reCAPTCHA icon.
=> Now create a index.html file inside the views folder and write down the below code,
index.html:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style>
body {
font-family: 'Helvetica', sans-serif;
color: #fff;
margin: 0px;
padding: 0px;
background-color: #ffe1c1;
width: 100%;
height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
}
.app__container {
width: 420px;
display: flex;
flex-direction: column;
margin: auto;
}
textarea {
margin-bottom: 10px;
height: 100px;
font-size: 20px;
}
button {
margin: auto;
background: #4267b2;
text-align: center;
padding: 7px 15px;
font-size: 20xpx;
text-decoration: none;
color: #fff;
font-weight: 400;
border: 0px;
width: 100%;
outline: none;
cursor: pointer;
}
</style>
</head>
<body>
<div class="app__container">
<textarea id="user-message" placeholder="Write some message"></textarea>
<button id="submit-button">Submit</button>
</div>
<script src="https://www.google.com/recaptcha/api.js?render=----SITE_KEY-----"></script>
<script>
const submitButton = document.querySelector('#submit-button');
function getCaptchaToken(callback) {
grecaptcha.ready( () => {
grecaptcha.execute('---SITE_KEY----', {action: 'submit_message'}).then( (token) => {
callback(token)
});;
});
}
submitButton.onclick = (event) => {
const userMessage = document.querySelector('#user-message').value;
if(userMessage === '' || userMessage === null) {
alert("Message Can't be empty");
return;
}
getCaptchaToken( (token) => {
fetch('/storeMessage', {
method: 'POST',
headers: {
'Content-Type': undefined
},
body: JSON.stringify({
message: userMessage,
token
})
})
.then((resp) => resp.json())
.then((result) => {
if(result.Code === 200) {
alert('Your message is submitted')
} else {
alert('Bots are not allowed')
}
})
.catch((error) => {
alert(error.Message)
});
});
}
</script>
</body>
</html>Explanation:
- In the above HTML file, first, we have very little CSS just to decorate the page so let’s skip that.
- Then we have few markups for displaying the Textbox and Button.
- Next, we have included script from google as shown below,
<script src="https://www.google.com/recaptcha/api.js?render=----SITE_KEY-----"></script>
- Then we have written few lines of javascript, which handles the form submission n all.
- First, we have created a contant
submitButton, which contains the instance of Submit Button. - Then we have created
getCaptchaToken()which given the Google Captcha token. - The
getCaptchaToken()function calls thegrecaptcha.ready. Thegrecaptcha.readyinitialize the Google Captcha Library. - Then
grecaptcha.executewill be called, this function returns the Authentication token, and this token will be sent to the server as a captcha response. - On Click on the submit button, we will call
getCaptchaToken(), which gives the token and then using fetch API we call/storeMessage. - The
/storeMessagewill expect two parameters in the Request Payloadmessageandtoken.
7. Verifying the captcha token
As you know /storeMessage API will call StoreMessage() function which should be created in route-handler.go file. The StoreMessage() function will call the google server to get a score of the authenticity of the Request.
=> Open theroute-handler.go and write down the below code,
route-handler.go:
package main
import (
"encoding/json"
"net/http"
"net/url"
"os"
"strings"
)
// RenderHome Rendering the Home Page
func RenderHome(response http.ResponseWriter, request *http.Request) {
http.ServeFile(response, request, "views/index.html")
}
// StoreMessage function will verify the Captcha
func StoreMessage(response http.ResponseWriter, request *http.Request) {
var storeMessageRequest StoreMessageRequest
var captchaVerifyResponse interface{}
var errorResponse = ErrorResponse{
Code: http.StatusInternalServerError, Message: "It's not you it's me.",
}
decoder := json.NewDecoder(request.Body)
decoderErr := decoder.Decode(&storeMessageRequest)
defer request.Body.Close()
if decoderErr != nil {
returnErrorResponse(response, request, errorResponse)
} else {
if storeMessageRequest.Message == "" {
errorResponse.Code = http.StatusBadRequest
errorResponse.Message = "Message can't be empty"
returnErrorResponse(response, request, errorResponse)
} else {
captchaPayloadRequest := url.Values{}
captchaPayloadRequest.Set("secret", os.Getenv("CAPTCHA_SECRET_KEY"))
captchaPayloadRequest.Set("response", storeMessageRequest.Token)
verifyCaptchaRequest, _ := http.NewRequest("POST", os.Getenv("VERIFY_CAPTCHA_GOOGLE_API"), strings.NewReader(captchaPayloadRequest.Encode()))
verifyCaptchaRequest.Header.Add("content-type", "application/x-www-form-urlencoded")
verifyCaptchaRequest.Header.Add("cache-control", "no-cache")
verifyCaptchaResponse, _ := http.DefaultClient.Do(verifyCaptchaRequest)
decoder := json.NewDecoder(verifyCaptchaResponse.Body)
decoderErr := decoder.Decode(&captchaVerifyResponse)
defer verifyCaptchaResponse.Body.Close()
if decoderErr != nil {
returnErrorResponse(response, request, errorResponse)
return
}
var successResponse = SuccessResponse{
Code: http.StatusOK,
Message: "Your request is verified",
Response: captchaVerifyResponse,
}
successJSONResponse, jsonError := json.Marshal(successResponse)
if jsonError != nil {
returnErrorResponse(response, request, errorResponse)
return
}
response.Header().Set("Content-Type", "application/json")
response.WriteHeader(successResponse.Code)
response.Write(successJSONResponse)
}
}
}
func returnErrorResponse(response http.ResponseWriter, request *http.Request, errorMesage ErrorResponse) {
httpResponse := &ErrorResponse{Code: errorMesage.Code, Message: errorMesage.Message}
jsonResponse, err := json.Marshal(httpResponse)
if err != nil {
panic(err)
}
response.Header().Set("Content-Type", "application/json")
response.WriteHeader(errorMesage.Code)
response.Write(jsonResponse)
}
Explanation:
- First, we decode the request Payload and store the data of request into
storeMessageRequestvariable. - Then the next step is to call google server, which in return, gives the authenticity score of Request.
- The
captchaPayloadRequestcontains the payload that we will send to google server. - Using
http.NewRequestwe make the POST request to the Google Server and we store the response incaptchaVerifyResponsevariable. - After that, we return the response to API by sending the
captchaVerifyResponsevariable in the response body.
8. Running the application
To run the application, you need to build the application and then run the executable file as shown below,
> go build > Google_reCaptcha_V3_in_GoLang_Tutorial.exe
Now you can test this application by opening thelocalhost:8000.
9. Conclusion
This Google Recaptcha V3 in GoLang Tutorial explained us how we can integrate Google Recaptcha(V3) in websites build in Golang. For now, that’s it, Meanwhile, you can play with code and if something doesn’t work let me know in comments. Feel free to share your opinions in the below comments box and if you like this article do share with your friends and colleagues.








