beego框架(golang)学习验证码

beego框架(golang)学习验证码

登录页面使用验证码

路由设置

/beego_admin_template/routers/router.go

get请求页面, post验证用户名密码和验证码

	beego.Router("/login", &admin.CommonController{}, 
    "get:LoginPage;post:Login")

当url输入 http://localhost:8080/login 时跳转到登录页面,显示验证码

控制器目录

/beego_admin_template/controllers/admin/common.go

package admin
import (
    "github.com/astaxie/beego"
    "github.com/astaxie/beego/cache"
    captcha2 "github.com/astaxie/beego/utils/captcha"
)

// 全局验证码结构体
var captcha *captcha2.Captcha

// init函数初始化captcha
func init()  {
    // 验证码功能
    // 使用Beego缓存存储验证码数据
    store := cache.NewMemoryCache()
    // 创建验证码
    captcha = captcha2.NewWithFilter("/captcha", store)
    // 设置验证码长度
    captcha.ChallengeNums = 4
    // 设置验证码模板高度
    captcha.StdHeight = 50
    // 设置验证码模板宽度
    captcha.StdWidth = 120
}

// 登录页面
func (c *CommonController)LoginPage()  {
    // 设置模板目录
    c.TplName = "admin/common/login.html"
}

登录页面

/beego_admin_template/views/admin/common/login.html

<div style="margin-left: 10px;">
    {{create_captcha}}
</div>

验证验证码

// 登录
func (c *CommonController)Login()  {
    // 验证码验证
    if !captcha.VerifyReq(c.Ctx.Request) {
        c.Data["Error"] = "验证码错误"
        return
    }

    // 其他代码
    …… 

    c.Redirect("/", 302)
}

captcha.go
// VerifyReq verify from a request
func (c *Captcha) VerifyReq(req *http.Request) bool {
    // 解析请求体
    req.ParseForm()
    // 读取请求参数调用Verify方法
    return c.Verify(req.Form.Get(c.FieldIDName), req.Form.Get(c.FieldCaptchaName))
}

// 验证验证码id和字符串
func (c *Captcha) Verify(id string, challenge string) (success bool) {
    if len(challenge) == 0 || len(id) == 0 {
        return
    }

    var chars []byte

    key := c.key(id)

    if v, ok := c.store.Get(key).([]byte); ok {
        chars = v
    } else {
        return
    }

    defer func() {
        // finally remove it
        c.store.Delete(key)
    }()

    if len(chars) != len(challenge) {
        return
    }
    // verify challenge
    for i, c := range chars {
        if c != challenge[i]-48 {
            return
        }
    }

    return true
}

注意点

在调试验证码的时候,会发现验证码老是错误,是因为默认验证码是存储在内存中,每次重启会删除内存

源码查看

文件:common.go

调用缓存包中的NewMemoryCache()函数,返回一个新的内存缓存指针地址

store := cache.NewMemoryCache()

文件:memory.go

MemoryCache是一个内存缓存适配器,它包含一个map带有读写锁的map存储

// MemoryCache is Memory cache adapter.
// it contains a RW locker for safe map storage.
type MemoryCache struct {
    sync.RWMutex
    dur   time.Duration
    items map[string]*MemoryItem
    Every int // run an expiration check Every clock time
}



// NewMemoryCache returns a new MemoryCache.
func NewMemoryCache() Cache {
    cache := MemoryCache{items: make(map[string]*MemoryItem)}
    return &cache
}

文件:common.go

NewWithFilter()方法创建一个新的验证码,并返回该验证码的指针

captcha = captcha2.NewWithFilter("/captcha", store)

文件 captcha.go

// 该方法创建了一个验证码在指定缓存中
// 增加了一个服务于验证码图片的过滤器
// 并且添加了一个用于输出html的模板函数

func NewWithFilter(urlPrefix string, store cache.Cache) *Captcha {
    // 生成验证码结构体
    cpt := NewCaptcha(urlPrefix, store)

    // 创建过滤器
    beego.InsertFilter(cpt.URLPrefix+"*", beego.BeforeRouter, cpt.Handler)

    // add to template func map
    beego.AddFuncMap("create_captcha", cpt.CreateCaptchaHTML)

    return cpt
}

其实 cpt.Handler需要好好看一下,里面包含了beego过滤器的使用

posted @ 2019-06-17 23:35  周起  阅读(2325)  评论(0编辑  收藏  举报