加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Go实战--golang中使用图片和验证码(dchest/captcha)

发布时间:2020-12-16 09:44:15 所属栏目:大数据 来源:网络整理
导读:声明不止,继续 go go go !!! 昨天分享了iris框架中,如何使用Google的recaptcha。今天就一起分享学一学golang中如何使用图片验证码以及语音验证码,当然最开始我们还是要面向github编程了。 使用recaptcha 其实recaptcha的使用很简单,这里不使用iris框架,

声明不止,继续 go go go !!!

昨天分享了iris框架中,如何使用Google的recaptcha。今天就一起分享学一学golang中如何使用图片验证码以及语音验证码,当然最开始我们还是要面向github编程了。

使用recaptcha

其实recaptcha的使用很简单,这里不使用iris框架,也很容易自己实现的。

https://github.com/haisum/recaptcha/blob/master/recaptcha.go

package recaptcha

import (
    "encoding/json"
    "io/ioutil"
    "net/http"
    "net/url"
    "time"
)

// R type represents an object of Recaptcha and has public property Secret,
// which is secret obtained from google recaptcha tool admin interface
type R struct {
    Secret    string
    lastError []string
}

// Struct for parsing json in google's response
type googleResponse struct {
    Success    bool
    ErrorCodes []string `json:"error-codes"`
}

// url to post submitted re-captcha response to
var postURL = "https://www.google.com/recaptcha/api/siteverify"

// Verify method,verifies if current request have valid re-captcha response and returns true or false
// This method also records any errors in validation.
// These errors can be received by calling LastError() method.
func (r *R) Verify(req http.Request) bool {
    response := req.FormValue("g-recaptcha-response")
    return r.VerifyResponse(response)
}

// VerifyResponse is a method similar to `Verify`; but doesn't parse the form for you. Useful if
// you're receiving the data as a JSON object from a javascript app or similar.
func (r *R) VerifyResponse(response string) bool {
    r.lastError = make([]string, 1)
    client := &http.Client{Timeout: 20 * time.Second}
    resp,err := client.PostForm(postURL,url.Values{"secret": {r.Secret},"response": {response}})
    if err != nil {
        r.lastError = append(r.lastError,err.Error())
        return false
    }
    defer resp.Body.Close()
    body,err := ioutil.ReadAll(resp.Body)
    if err != nil {
        r.lastError = append(r.lastError,err.Error())
        return false
    }
    gr := new(googleResponse)
    err = json.Unmarshal(body,gr)
    if err != nil {
        r.lastError = append(r.lastError,err.Error())
        return false
    }
    if !gr.Success {
        r.lastError = append(r.lastError,gr.ErrorCodes...)
    }
    return gr.Success
}

// LastError returns errors occurred in last re-captcha validation attempt
func (r R) LastError() []string {
    return r.lastError
}

使用:

package main

import (
    "fmt"
    "log"
    "net/http"

    "github.com/haisum/recaptcha"
)

func main() {
    sitekey := "6LfiVjcUAAAAAJyjCEGVyTpmFqlpOMGVIZpZPy6p"
    re := recaptcha.R{
        Secret: "6LfiVjcUAAAAAJ7wALWYNew2yx0qbT0WxRR-kYu9",}

    form := fmt.Sprintf(` <html> <head> <script src='https://www.google.com/recaptcha/api.js'></script> </head> <body> <form action="/submit" method="post"> <div class="g-recaptcha" data-sitekey="%s"></div> <input type="submit"> </form> </body> </html> `,sitekey)

    http.HandleFunc("/",func(w http.ResponseWriter,r *http.Request) {
        fmt.Fprintf(w,form)
    })
    http.HandleFunc("/submit",r *http.Request) {
        isValid := re.Verify(*r)
        if isValid {
            fmt.Fprintf(w,"Valid")
        } else {
            fmt.Fprintf(w,"Invalid! These errors ocurred: %v",re.LastError())
        }
    })

    log.Printf("n Starting server on http://localhost:8080 .")

    err := http.ListenAndServe(":8080",nil)

    if err != nil {
        log.Fatalf("Could not start server. %s",err)
    }
}

dchest/captcha

上面是小试牛刀,现在开始一起了解dchest/captcha。

github地址:
https://github.com/dchest/captcha

Star: 619

文档地址:
https://godoc.org/github.com/dchest/captcha

获取:
go get github.com/dchest/captcha

常量

const (
    // Default number of digits in captcha solution.
    DefaultLen = 6
    // The number of captchas created that triggers garbage collection used
    // by default store.
    CollectNum = 100
    // Expiration time of captchas used by default store.
    Expiration = 10 * time.Minute

    // Standard width and height of a captcha image.
    StdWidth  = 240
    StdHeight = 80
)

默认是六位的验证码
当达到100个验证码的时候,会进行垃圾回收
验证码十分钟过期
图片验证码尺寸240*80

func New

func New() string

New creates a new captcha with the standard length,saves it in the internal storage and returns its id.
创建一个6位的验证码,存入内存,并返回id
func NewLen

func NewLen(length int) (id string)

NewLen is just like New,but accepts length of a captcha solution as the argument.
跟new的作用一样,就是多了一个参数,可以自定义验证码的位数。

func RandomDigits

func RandomDigits(length int) []byte

RandomDigits returns a byte slice of the given length containing pseudorandom numbers in range 0-9. The slice can be used as a captcha solution.
生成随机数,返回切片,长度为length

func Reload

func Reload(id string) bool

Reload generates and remembers new digits for the given captcha id. This function returns false if there is no captcha with the given id.
刷新,也就是重新载入,但是验证码id是不变的。

func Server

func Server(imgWidth,imgHeight int) http.Handler

Server returns a handler that serves HTTP requests with image or audio representations of captchas. Image dimensions are accepted as arguments. The server decides which captcha to serve based on the last URL path component: file name part must contain a captcha id,file extension — its format (PNG or WAV).

func SetCustomStore

func SetCustomStore(s Store)

SetCustomStore sets custom storage for captchas,replacing the default memory store. This function must be called before generating any captchas.
设置本地存储验证码而不是内存。

func Verify

func Verify(id string,digits []byte) bool

Verify returns true if the given digits are the ones that were used to create the given captcha id.

The function deletes the captcha with the given id from the internal storage,so that the same captcha can’t be verified anymore.
验证

func VerifyString

func VerifyString(id string,digits string) bool

VerifyString is like Verify,but accepts a string of digits. It removes spaces and commas from the string,but any other characters,apart from digits and listed above,will cause the function to return false.
验证

应用

// Copyright 2011 Dmitry Chestnykh. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

// example of HTTP server that uses the captcha package.
package main

import (
    "fmt"
    "io"
    "log"
    "net/http"
    "text/template"

    "github.com/dchest/captcha"
)

var formTemplate = template.Must(template.New("example").Parse(formTemplateSrc))

func showFormHandler(w http.ResponseWriter,r *http.Request) {
    if r.URL.Path != "/" {
        http.NotFound(w,r)
        return
    }
    d := struct {
        CaptchaId string
    }{
        captcha.NewLen(4),}
    if err := formTemplate.Execute(w,&d); err != nil {
        http.Error(w,err.Error(),http.StatusInternalServerError)
    }
}

func processFormHandler(w http.ResponseWriter,r *http.Request) {
    w.Header().Set("Content-Type","text/html; charset=utf-8")
    if !captcha.VerifyString(r.FormValue("captchaId"),r.FormValue("captchaSolution")) {
        io.WriteString(w,"Wrong captcha solution! No robots allowed!n")
    } else {
        io.WriteString(w,"Great job,human! You solved the captcha.n")
    }
    io.WriteString(w,"<br><a href='/'>Try another one</a>")
}

func main() {
    http.HandleFunc("/",showFormHandler)
    http.HandleFunc("/process",processFormHandler)
    http.Handle("/captcha/",captcha.Server(captcha.StdWidth,captcha.StdHeight))
    fmt.Println("Server is at localhost:8080")
    if err := http.ListenAndServe("localhost:8080",nil); err != nil {
        log.Fatal(err)
    }
}

const formTemplateSrc = `<!doctype html> <head><title>Captcha Example</title></head> <body> <script> function setSrcQuery(e,q) { var src = e.src; var p = src.indexOf('?'); if (p >= 0) { src = src.substr(0,p); } e.src = src + "?" + q } function playAudio() { var le = document.getElementById("lang"); var lang = le.options[le.selectedIndex].value; var e = document.getElementById('audio') setSrcQuery(e,"lang=" + lang) e.style.display = 'block'; e.autoplay = 'true'; return false; } function changeLang() { var e = document.getElementById('audio') if (e.style.display == 'block') { playAudio(); } } function reload() { setSrcQuery(document.getElementById('image'),"reload=" + (new Date()).getTime()); setSrcQuery(document.getElementById('audio'),(new Date()).getTime()); return false; } </script> <select id="lang" onchange="changeLang()"> <option value="en">English</option> <option value="ja">Japanese</option> <option value="ru">Russian</option> <option value="zh">Chinese</option> </select> <form action="/process" method=post> <p>Type the numbers you see in the picture below:</p> <p><img id=image src="/captcha/{{.CaptchaId}}.png" alt="Captcha image"></p> <a href="#" onclick="reload()">Reload</a> | <a href="#" onclick="playAudio()">Play Audio</a> <audio id=audio controls style="display:none" src="/captcha/{{.CaptchaId}}.wav" preload=none> You browser doesn't support audio. <a href="/captcha/download/{{.CaptchaId}}.wav">Download file</a> to play it in the external player. </audio> <input type=hidden name=captchaId value="{{.CaptchaId}}"><br> <input name=captchaSolution> <input type=submit value=Submit> </form> `

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读