2 Star 0 Fork 0

hero/momo

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
captcha.go 4.62 KB
一键复制 编辑 原始数据 按行查看 历史
hero 提交于 2024-11-05 14:11 . upd:captcha
package controller
import (
"crypto/md5"
"encoding/hex"
"encoding/json"
"fmt"
"log"
"os"
"strconv"
"strings"
"sync"
"time"
images "gitee.com/linqwen/momo/app/rbac/captcha/assets/resources/images"
tiles "gitee.com/linqwen/momo/app/rbac/captcha/assets/resources/tiles"
slide "gitee.com/linqwen/momo/app/rbac/captcha/slide"
"gitee.com/linqwen/momo/igin"
"gitee.com/linqwen/momo/utils"
)
var slideBasicCapt slide.Captcha
func init() {
builder := slide.NewBuilder(
//slide.WithGenGraphNumber(2),
slide.WithEnableGraphVerticalRandom(true),
)
// background images
imgs, err := images.GetImages()
if err != nil {
log.Fatalln(err)
}
graphs, err := tiles.GetTiles()
if err != nil {
log.Fatalln(err)
}
var newGraphs = make([]*slide.GraphImage, 0, len(graphs))
for i := 0; i < len(graphs); i++ {
graph := graphs[i]
newGraphs = append(newGraphs, &slide.GraphImage{
OverlayImage: graph.OverlayImage,
MaskImage: graph.MaskImage,
ShadowImage: graph.ShadowImage,
})
}
// set resources
builder.SetResources(
slide.WithGraphImages(newGraphs),
slide.WithBackgrounds(imgs),
)
slideBasicCapt = builder.Make()
}
type captchaController struct {
}
func CaptchaRouter(r igin.IRouterGroup) {
c := &captchaController{}
router := r.Group("api/captcha")
{
router.GET("/slide-data", c.getSlideCaptchaData)
router.POST("/slide-check", c.checkSlideCaptchaData)
}
}
func (bc *captchaController) getSlideCaptchaData(c igin.IContext) {
captData, err := slideBasicCapt.Generate()
if err != nil {
utils.ResponseApiError(c, 400, "生成验证码失败", err.Error())
return
}
blockData := captData.GetData()
if blockData == nil {
utils.ResponseApiError(c, 400, "生成验证码失败", nil)
return
}
var masterImageBase64, tileImageBase64 string
masterImageBase64 = captData.GetMasterImage().ToBase64()
tileImageBase64 = captData.GetTileImage().ToBase64()
dotsByte, _ := json.Marshal(blockData)
key := StringToMD5(string(dotsByte))
WriteCache(key, dotsByte)
data := map[string]interface{}{
"code": 0,
"captcha_key": key,
"image_base64": masterImageBase64,
"tile_base64": tileImageBase64,
"tile_width": blockData.Width,
"tile_height": blockData.Height,
"tile_x": blockData.TileX,
"tile_y": blockData.TileY,
}
utils.ResponseApiOk(c, "ok", data)
}
func (bc *captchaController) checkSlideCaptchaData(c igin.IContext) {
var dto struct {
Point string `binding:"required" json:"Point" form:"Point"`
Key string `binding:"required" json:"Key" form:"Key"`
}
// dto := struct {
// Point string `binding:"required" json:"Point" form:"Point"`
// Key string `binding:"required" json:"Key" form:"Key"`
// }{}
if err := c.ShouldBind(&dto); err != nil {
utils.ResponseApiError(c, 400, err.Error(), nil)
return
}
cacheDataByte := ReadCache(dto.Key)
if len(cacheDataByte) == 0 {
utils.ResponseApiError(c, 400, "illegal key", nil)
return
}
src := strings.Split(dto.Point, ",")
var dct *slide.Block
if err := json.Unmarshal(cacheDataByte, &dct); err != nil {
utils.ResponseApiError(c, 400, "illegal key", nil)
return
}
chkRet := false
if 2 == len(src) {
sx, _ := strconv.ParseFloat(fmt.Sprintf("%v", src[0]), 64)
sy, _ := strconv.ParseFloat(fmt.Sprintf("%v", src[1]), 64)
chkRet = slide.CheckPoint(int64(sx), int64(sy), int64(dct.X), int64(dct.Y), 4)
}
if chkRet {
utils.ResponseApiOk(c, "验证成功", nil)
return
}
utils.ResponseApiError(c, 400, "验证失败", nil)
return
}
// GetPWD .
func GetPWD() string {
path, err := os.Getwd()
if err != nil {
return ""
}
return path
}
// StringToMD5 MD5
func StringToMD5(src string) string {
m := md5.New()
m.Write([]byte(src))
res := hex.EncodeToString(m.Sum(nil))
return res
}
type cachedata = struct {
data []byte
createAt time.Time
}
var mux sync.Mutex
var cachemaps = make(map[string]*cachedata)
// WriteCache .
func WriteCache(key string, data []byte) {
mux.Lock()
defer mux.Unlock()
cachemaps[key] = &cachedata{
createAt: time.Now(),
data: data,
}
}
// ReadCache .
func ReadCache(key string) []byte {
mux.Lock()
defer mux.Unlock()
if cd, ok := cachemaps[key]; ok {
return cd.data
}
return []byte{}
}
type Block struct {
X int `json:"x"`
Y int `json:"y"`
Width int `json:"width"`
Height int `json:"height"`
Angle int `json:"angle"`
TileX int `json:"tile_x"`
TileY int `json:"tile_y"`
}
// CheckPoint is the position of the detection point
func CheckPoint(sx, sy, dx, dy, padding int64) bool {
newX := padding * 2
newY := padding * 2
newDx := dx - padding
newDy := dy - padding
return sx >= newDx &&
sx <= newDx+newX &&
sy >= newDy &&
sy <= newDy+newY
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/linqwen/momo.git
git@gitee.com:linqwen/momo.git
linqwen
momo
momo
v1.0.3

搜索帮助

0d507c66 1850385 C8b1a773 1850385