Golang Beego implementing and using CAPTCHA
In this small tutorial I'll show you how to use CAPTCHA validation inside your application. We won't be using the builtin CAPTCHA of Beego but instead use another package of GitHub user dchest
1, and his package captcha2.Prerequisites
Assuming you have your Beego application set and running, go get the captcha package.
go get github.com/dchest/captcha
CAPTCHA controller
Now lets create a controller that generates the CAPTCHA and sends it the the clients browser.
YourBeegoApplication/controllers/Captcha.go
package controllers
import (
"BeegoCaptchaTutorial/models"
"bytes"
"github.com/astaxie/beego"
"github.com/dchest/captcha"
)
type CaptchaController struct {
beego.Controller
}
func (this *CaptchaController) Get() {
// Create a new Captcha
ValidationString := captcha.New()
// Store the string for validation later
models.StoreString = ValidationString
// Create the captcha image
var ImageBuffer bytes.Buffer
captcha.WriteImage(&ImageBuffer, ValidationString, 300, 90)
// Send Out the headers of the image
this.Ctx.Output.Header("Cache-Control", "no-cache, no-store, must-revalidate")
this.Ctx.Output.Header("Pragma", "no-cache")
this.Ctx.Output.Header("Expires", "0")
this.Ctx.Output.Header("Content-Type", "image/png")
// Send out the image itself
this.Ctx.Output.Body(ImageBuffer.Bytes())
}
The code is self explaining, you create a new CAPTCHA from the package we just downloaded, the New() function returns a string. From this string the package can generate digits for the image, and the other way around, the digits to the original string so we can validate it later.
We store the string in a model, which we still have to create.
Create a bytes buffer to store the generated image in, which the function WriteImage() does. The parameters of this function are
- io.Writer, a buffer to save the image in
- A string, the string we created with the New function
- Width of the image
- Heigth of the image
Then we send the correct headers to the client who requests the image. The cache-control is meant so whenever a client refreshes the image, they get served a new one instead of a cached version in their browser.
And last we send the image itself to the client.
Create a model to store the string in
The model itself for this example will be very short, and quite 'static'. In a production environment you'll need some more dynamic storing mechanism, maybe per IP address or by session so every client gets a different key assigned to them.
YourBeegoApplication/models/CaptchaStore.go
package models
var StoreString string
Setup a route
In YourBeegoApplication/routers/route.go init() scope add the following route, so Beego can present the CAPTCHA image to the clients.
beego.Router("/captcha.png", &controllers.CaptchaController{})
Example use
Now lets create a simple form that shows the CAPTCHA image, and asks to fill in the answser. It will look like this:
Create a template
Create a template file under YourBeegoApplication/views/ folder, in this example I'll use form.tpl
<form action="/form" method="post">
<img src="/captcha.png"><br />
<input type="text" id="captcha" name="captcha">
<input type="submit" value="Submit">
</form>
{{if .Correct}}Captcha was entered correctly!{{end}}
{{if .Incorrect}}Captcha was wrong, try again!{{end}}
Create a controller for the form
Now we need a controller that shows the form and validates it. My controller is named FormController and saved under YourBeego/controllers/form.go
package controllers
import (
"BeegoCaptchaTutorial/models"
"github.com/astaxie/beego"
"github.com/dchest/captcha"
)
type FormController struct {
beego.Controller
}
func (this *FormController) Get() {
this.TplName = "form.tpl"
}
func (this *FormController) Post() {
// Get the captcha input from the form
CaptchaInput := this.GetString("captcha")
// Validate the captcha
if captcha.VerifyString(models.StoreString, CaptchaInput) {
this.Data["Correct"] = true
} else {
this.Data["Incorrect"] = true
}
this.TplName = "form.tpl"
}
We import our models so we can access the CAPTCHA string that gets stored by its controller. We also import the CAPTCHA package because we need the validation function from it. And of course our Beego package.
The Get() function just shows the template, form.tpl on a normal request.
The Post() function gets called whenever the form is posted to this controller.
We validate the input with VerifyString() which takes the following arguments;
- The string that was generated by New() in our CaptchaController
- The user input from the form
Set up a route to this controller
Again, in YourBeegoApplication/routers/route.go init() scope add the following line.
beego.Router("/form", &controllers.FormController{})
Et voila, you can now go to your webpage/form and see the result!
https://github.com/dchest/captcha
cached copy