support captcha

This commit is contained in:
yanghao05
2023-02-04 16:24:08 +08:00
parent 384677f071
commit 1c2b861ac7
13 changed files with 138 additions and 57 deletions

View File

@@ -6,7 +6,7 @@ KeyLong = 6
ImgWidth = 240 #验证码宽度
ImgHeight = 80 # 验证码高度
OpenCaptcha = 0 # 防爆破验证码开启此数0代表每次登录都需要验证码其他数字代表错误密码此数如3代表错误三次后出现验证码
OpenCaptchaTimeOut = 1h # 防爆破验证码超时时间单位s(秒)
OpenCaptchaTimeOut = "1h" # 防爆破验证码超时时间单位s(秒)
[Storage]
Driver = "local"

7
go.mod
View File

@@ -9,6 +9,7 @@ require (
github.com/go-gormigrate/gormigrate/v2 v2.0.2
github.com/gofrs/uuid v4.0.0+incompatible
github.com/golang-jwt/jwt/v4 v4.4.3
github.com/mojocn/base64Captcha v1.3.5
github.com/pkg/errors v0.9.1
github.com/rogeecn/fabfile v1.3.0
github.com/rogeecn/gen v1.0.4
@@ -35,11 +36,12 @@ require (
github.com/glebarez/sqlite v1.5.0 // indirect
github.com/go-playground/locales v0.14.0 // indirect
github.com/go-playground/universal-translator v0.18.0 // indirect
github.com/go-playground/validator/v10 v10.10.0 // indirect
github.com/go-playground/validator/v10 v10.11.1 // indirect
github.com/go-sql-driver/mysql v1.6.0 // indirect
github.com/goccy/go-json v0.9.7 // indirect
github.com/goccy/go-json v0.9.11 // indirect
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect
github.com/golang-sql/sqlexp v0.1.0 // indirect
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
@@ -72,6 +74,7 @@ require (
github.com/ugorji/go/codec v1.2.7 // indirect
go.uber.org/atomic v1.9.0 // indirect
go.uber.org/multierr v1.8.0 // indirect
golang.org/x/image v0.0.0-20190802002840-cff245a6509b // indirect
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
golang.org/x/net v0.4.0 // indirect
golang.org/x/sys v0.3.0 // indirect

12
go.sum
View File

@@ -109,13 +109,11 @@ github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb
github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho=
github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
github.com/go-playground/validator/v10 v10.10.0 h1:I7mrTYv78z8k8VXa/qJlOlEXn/nBh+BF8dHX5nt/dr0=
github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos=
github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ=
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/goccy/go-json v0.9.7 h1:IcB+Aqpx/iMHu5Yooh7jEzJk1JZ7Pjtmys2ukPr7EeM=
github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk=
github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw=
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
@@ -129,6 +127,8 @@ github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2V
github.com/golang-sql/sqlexp v0.0.0-20170517235910-f1bb20e5a188/go.mod h1:vXjM/+wXQnTPR4KqTKDgJukSZ6amVRtWMPEjE6sQoK8=
github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A=
github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
@@ -309,6 +309,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8=
github.com/mojocn/base64Captcha v1.3.5 h1:Qeilr7Ta6eDtG4S+tQuZ5+hO+QHbiGAJdi4PfoagaA0=
github.com/mojocn/base64Captcha v1.3.5/go.mod h1:/tTTXn4WTpX9CfrmipqRytCpJ27Uw3G6I7NcP2WwcmY=
github.com/montanaflynn/stats v0.6.6/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU=
github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek=
@@ -443,6 +445,8 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190501045829-6d32002ffd75/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=

6
go.work Normal file
View File

@@ -0,0 +1,6 @@
go 1.19
use (
.
../gen
)

15
go.work.sum Normal file
View File

@@ -0,0 +1,15 @@
github.com/go-playground/validator/v10 v10.11.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU=
github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0=
github.com/jackc/pgproto3 v1.1.0 h1:FYYE4yRw+AgI8wXIinMlNjBbp/UitDJwfj5LqqewP1A=
github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas=
github.com/ugorji/go v1.2.7 h1:qYhyWUUd6WbiM+C6JZAUkIJt/1WrjzNHY9+KCIjVqTo=
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220924013350-4ba4fb4dd9e7/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/net v0.0.0-20220923203811-8be639271d50/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=

View File

@@ -1,44 +1,31 @@
package controller
import (
"atom/modules/system/dto"
"atom/providers/captcha"
"atom/providers/config"
"errors"
"github.com/gin-gonic/gin"
"github.com/mojocn/base64Captcha"
)
type CaptchaController interface {
Show(*gin.Context) (dto.SysCaptchaResponse, error)
Show(*gin.Context) (*captcha.CaptchaResponse, error)
}
type captchaControllerImpl struct {
conf *config.Config
conf *config.Config
captcha *captcha.Captcha
}
func NewCaptchaController(conf *config.Config) CaptchaController {
return &captchaControllerImpl{conf: conf}
}
func (c *captchaControllerImpl) Show(ctx *gin.Context) (dto.SysCaptchaResponse, error) {
// 判断验证码是否开启
var store = base64Captcha.DefaultMemStore
// 字符,公式,验证码配置
// 生成默认数字的driver
driver := base64Captcha.NewDriverDigit(c.conf.Captcha.ImgHeight, c.conf.Captcha.ImgWidth, c.conf.Captcha.KeyLong, 0.7, 80)
// cp := base64Captcha.NewCaptcha(driver, store.UseWithCtx(c)) // v8下使用redis
cp := base64Captcha.NewCaptcha(driver, store)
id, b64s, err := cp.Generate()
if err != nil {
return dto.SysCaptchaResponse{}, errors.New("验证码获取失败")
func NewCaptchaController(
conf *config.Config,
captcha *captcha.Captcha,
) CaptchaController {
return &captchaControllerImpl{
conf: conf,
captcha: captcha,
}
return dto.SysCaptchaResponse{
CaptchaId: id,
PicPath: b64s,
CaptchaLength: c.conf.Captcha.KeyLong,
OpenCaptcha: c.conf.Captcha.OpenCaptcha != 0,
}, nil
}
func (c *captchaControllerImpl) Show(ctx *gin.Context) (*captcha.CaptchaResponse, error) {
return c.captcha.Generate()
}

View File

@@ -1,8 +1 @@
package dto
type SysCaptchaResponse struct {
CaptchaId string `json:"captcha_id,omitempty"`
PicPath string `json:"pic_path,omitempty"`
CaptchaLength int `json:"captcha_length,omitempty"`
OpenCaptcha bool `json:"open_captcha,omitempty"`
}

View File

@@ -18,5 +18,5 @@ func NewRoute(captcha controller.CaptchaController, svc *http.Service) contracts
}
func (r *Route) Register() {
r.svc.Engine.GET("/captcha", gen.DataFunc(r.captcha.GetName))
r.svc.Engine.GET("/captcha", gen.DataFunc(r.captcha.Show))
}

View File

@@ -2,12 +2,9 @@ package service
import (
"atom/modules/system/dao"
"atom/modules/system/dto"
"context"
)
type SystemService interface {
GetName(ctx context.Context) (dto.Name, error)
}
type systemService struct {
@@ -17,10 +14,3 @@ type systemService struct {
func NewSystemService(dao dao.Dao) SystemService {
return &systemService{dao: dao}
}
func (svc *systemService) GetName(ctx context.Context) (dto.Name, error) {
if err := svc.dao.Release(ctx, 10, "Rogee"); err != nil {
return dto.Name{}, err
}
return dto.Name{Name: "System.GetName"}, nil
}

View File

@@ -0,0 +1,55 @@
package captcha
import (
"atom/container"
"atom/providers/config"
"errors"
"log"
"github.com/mojocn/base64Captcha"
)
func init() {
if err := container.Container.Provide(NewCaptcha); err != nil {
log.Fatal(err)
}
}
type CaptchaResponse struct {
CaptchaId string `json:"captcha_id,omitempty"`
PicPath string `json:"pic_path,omitempty"`
CaptchaLength uint `json:"captcha_length,omitempty"`
OpenCaptcha uint `json:"open_captcha,omitempty"`
}
type Captcha struct {
conf *config.Config
captcha *base64Captcha.Captcha
}
func NewCaptcha(conf *config.Config, driver base64Captcha.Driver) (*Captcha, error) {
var store = base64Captcha.DefaultMemStore
return &Captcha{
conf: conf,
captcha: base64Captcha.NewCaptcha(driver, store),
}, nil
}
func (c *Captcha) Generate() (*CaptchaResponse, error) {
id, b64s, err := c.captcha.Generate()
if err != nil {
return nil, errors.New("验证码获取失败")
}
return &CaptchaResponse{
CaptchaId: id,
PicPath: b64s,
CaptchaLength: c.conf.Captcha.KeyLong,
OpenCaptcha: c.conf.Captcha.OpenCaptcha,
}, nil
}
func (c *Captcha) Verify(id, answer string) bool {
return c.captcha.Verify(id, answer, false)
}

View File

@@ -0,0 +1,26 @@
package storage
import (
"atom/container"
"atom/providers/config"
"log"
"github.com/mojocn/base64Captcha"
)
func init() {
if err := container.Container.Provide(NewCaptchaDriverDigit); err != nil {
log.Fatal(err)
}
}
func NewCaptchaDriverDigit(conf *config.Config) (base64Captcha.Driver, error) {
// 字符,公式,验证码配置
// 生成默认数字的driver
return base64Captcha.NewDriverDigit(
int(conf.Captcha.ImgHeight),
int(conf.Captcha.ImgWidth),
int(conf.Captcha.KeyLong),
0.7,
80), nil
}

View File

@@ -6,10 +6,10 @@ import (
)
type Captcha struct {
KeyLong int // 验证码长度
ImgWidth int // 验证码宽度
ImgHeight int // 验证码高度
OpenCaptcha int // 防爆破验证码开启此数0代表每次登录都需要验证码其他数字代表错误密码此数如3代表错误三次后出现验证码
KeyLong uint // 验证码长度
ImgWidth uint // 验证码宽度
ImgHeight uint // 验证码高度
OpenCaptcha uint // 防爆破验证码开启此数0代表每次登录都需要验证码其他数字代表错误密码此数如3代表错误三次后出现验证码
OpenCaptchaTimeOut string // 防爆破验证码超时时间单位s(秒)
}

View File

@@ -1,6 +1,8 @@
package providers
import (
_ "atom/providers/captcha"
_ "atom/providers/captcha/driver"
_ "atom/providers/config"
_ "atom/providers/database"
_ "atom/providers/faker"