From 02615c14065b2175fb1f82e9fe8cc077cc7e1621 Mon Sep 17 00:00:00 2001 From: izghua <2067930913@qq.com> Date: Sat, 11 May 2019 01:54:52 +0800 Subject: [PATCH] :pushpin: login --- common/struct.go | 8 ++- conf/const.go | 2 + conf/e.go | 7 +++ go.mod | 1 + router/auth/auth.go | 112 ++++++++++++++++++++++++++++++++++++-- router/router.go | 16 ++++-- service/auth.go | 50 +++++++++++++++++ validate/auth_login.go | 8 +-- validate/auth_register.go | 56 +++++++++++++++++++ validate/v.go | 14 +++-- 10 files changed, 252 insertions(+), 22 deletions(-) create mode 100644 service/auth.go create mode 100644 validate/auth_register.go diff --git a/common/struct.go b/common/struct.go index edc0728..7bce624 100644 --- a/common/struct.go +++ b/common/struct.go @@ -37,13 +37,19 @@ type LinkStore struct { Order int `json:"order"` } -type AuthRegister struct { +type AuthLogin struct { Email string `json:"email"` Password string `json:"password"` Captcha string `json:"captcha"` CaptchaKey string `json:"captchaKey"` } +type AuthRegister struct { + UserName string `json:"userName"` + Email string `json:"email"` + Password string `json:"password"` +} + type ConsolePostList struct { Post ConsolePost `json:"post,omitempty"` Tags []ConsoleTag `json:"tags,omitempty"` diff --git a/conf/const.go b/conf/const.go index 225d77b..c671cb1 100644 --- a/conf/const.go +++ b/conf/const.go @@ -66,5 +66,7 @@ const ( Keywords = "默认关键词,叶落山城秋" Description = "个人网站,https://github.com/izghua/go-blog" RecordNumber = "000-0000" + + UserCnt = 2 ) diff --git a/conf/e.go b/conf/e.go index c731454..b4b429b 100644 --- a/conf/e.go +++ b/conf/e.go @@ -13,6 +13,7 @@ var Msg = map[int]string{ 400001001: "控制器参数断言失败,请检查后再试", 400001002: "数据类型转换失败,请检查后再试", 400001003: "表单参数获取失败,请检查后再试", + 400001004: "数据获取失败,请检查后再试", //post 401000000: "文章标题不能为空,请检查后再试", @@ -78,5 +79,11 @@ var Msg = map[int]string{ 407000005: "验证码长度不正确,请检查后再试", 407000006: "验证码key不存在,请检查后再试", 407000007: "验证码key长度不正确,请检查后再试", + 407000008: "验证码不正确,请检查后再试", + 407000009: "用户数据获取失败,请检查后再试", + 407000010: "用户名账号或密码不正确,请检查后再试", + 407000011: "登录失败,请检查后再试", + 407000012: "用户名不能为空,请检查后再试", + 407000013: "用户名长度超出,请检查后再试", } diff --git a/go.mod b/go.mod index b6cdef0..be9e999 100644 --- a/go.mod +++ b/go.mod @@ -13,6 +13,7 @@ require ( github.com/qiniu/x v7.0.8+incompatible // indirect github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect github.com/speps/go-hashids v2.0.0+incompatible + golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 gopkg.in/russross/blackfriday.v2 v2.0.0-00010101000000-000000000000 qiniupkg.com/x v7.0.8+incompatible // indirect ) diff --git a/router/auth/auth.go b/router/auth/auth.go index 041d4b9..26c0ab9 100644 --- a/router/auth/auth.go +++ b/router/auth/auth.go @@ -8,11 +8,18 @@ package auth import ( "github.com/gin-gonic/gin" + "github.com/go-redis/redis" "github.com/izghua/go-blog/common" + "github.com/izghua/go-blog/conf" + "github.com/izghua/go-blog/service" "github.com/izghua/zgh" "github.com/izghua/zgh/gin/api" + "github.com/izghua/zgh/jwt" "github.com/mojocn/base64Captcha" + "golang.org/x/crypto/bcrypt" "net/http" + "strconv" + "time" ) type ConsoleAuth interface { @@ -30,15 +37,74 @@ func NewAuth() ConsoleAuth { return &Auth{} } -func (c *Auth) Register(ctx *gin.Context) { +// customizeRdsStore An object implementing Store interface +type customizeRdsStore struct { + redisClient *redis.Client +} +// customizeRdsStore implementing Set method of Store interface +func (s *customizeRdsStore) Set(id string, value string) { + err := s.redisClient.Set(id, value, time.Minute*10).Err() + if err != nil { + zgh.ZLog().Error("message","auth.AuthLogin","error",err.Error()) + } } -func (c *Auth) AuthRegister(ctx *gin.Context) { +// customizeRdsStore implementing Get method of Store interface +func (s *customizeRdsStore) Get(id string, clear bool) (value string) { + val, err := s.redisClient.Get(id).Result() + if err != nil { + zgh.ZLog().Error("message","auth.AuthLogin","error",err.Error()) + return + } + if clear { + err := s.redisClient.Del(id).Err() + if err != nil { + zgh.ZLog().Error("message","auth.AuthLogin","error",err.Error()) + return + } + } + return val +} + +func (c *Auth) Register(ctx *gin.Context) { + appG := api.Gin{C: ctx} + cnt,err := service.GetUserCnt() + if err != nil { + zgh.ZLog().Error("message","auth.Register","error",err.Error()) + appG.Response(http.StatusOK,400001004,nil) + return + } + if cnt >= conf.UserCnt { + zgh.ZLog().Error("message","auth.Register","error","User cnt beyond expectation") + appG.Response(http.StatusOK,400001004,nil) + return + } + appG.Response(http.StatusOK,0,nil) + return +} +func (c *Auth) AuthRegister(ctx *gin.Context) { + appG := api.Gin{C: ctx} + requestJson,exists := ctx.Get("json") + if !exists { + zgh.ZLog().Error("message","auth.AuthRegister","error","get request_params from context fail") + appG.Response(http.StatusOK,401000004,nil) + return + } + ar,ok := requestJson.(common.AuthRegister) + if !ok { + zgh.ZLog().Error("message","auth.AuthRegister","error","request_params turn to error") + appG.Response(http.StatusOK,400001001,nil) + return + } + service.UserStore(ar) + appG.Response(http.StatusOK,0,nil) + return } func (c *Auth) Login(ctx *gin.Context) { appG := api.Gin{C: ctx} - + customStore := customizeRdsStore{conf.CacheClient} + base64Captcha.SetCustomStore(&customStore) var configD = base64Captcha.ConfigDigit{ Height: 80, Width: 240, @@ -62,13 +128,47 @@ func (c *Auth) AuthLogin(ctx *gin.Context) { appG.Response(http.StatusOK,401000004,nil) return } - ar,ok := requestJson.(common.AuthRegister) + al,ok := requestJson.(common.AuthLogin) if !ok { zgh.ZLog().Error("message","auth.AuthLogin","error","request_params turn to error") appG.Response(http.StatusOK,400001001,nil) return } - verifyResult := base64Captcha.VerifyCaptcha(ar.CaptchaKey, ar.Captcha) - appG.Response(http.StatusOK,0,verifyResult) + verifyResult := base64Captcha.VerifyCaptcha(al.CaptchaKey, al.Captcha) + if !verifyResult { + zgh.ZLog().Error("message","auth.AuthLogin","error","captcha is error") + appG.Response(http.StatusOK,407000008,nil) + return + } + + user,err := service.GetUserByEmail(al.Email) + if err != nil { + zgh.ZLog().Error("message","auth.AuthLogin","error",err.Error()) + appG.Response(http.StatusOK,407000009,nil) + return + } + if user.Id <= 0 { + zgh.ZLog().Error("message","auth.AuthLogin","error","Can get user") + appG.Response(http.StatusOK,407000009,nil) + return + } + + password := []byte(al.Password) + hashedPassword := []byte(user.Password) + err = bcrypt.CompareHashAndPassword(hashedPassword,password) + if err != nil { + zgh.ZLog().Error("message","auth.AuthLogin","error",err.Error()) + appG.Response(http.StatusOK,407000010,nil) + return + } + + userIdStr := strconv.Itoa(user.Id) + token,err := jwt.CreateToken(userIdStr) + if err != nil { + zgh.ZLog().Error("message","auth.AuthLogin","error",err.Error()) + appG.Response(http.StatusOK,407000011,nil) + return + } + appG.Response(http.StatusOK,0,token) return } diff --git a/router/router.go b/router/router.go index 8eb81c8..686e911 100644 --- a/router/router.go +++ b/router/router.go @@ -31,6 +31,7 @@ func RoutersInit() *gin.Engine{ trash := console.NewTrash() consoleSystem := console.NewHome() consoleLink := console.NewLink() + consoleAuth := auth.NewAuth() c := r.Group("/console") { p := c.Group("/post") @@ -80,12 +81,17 @@ func RoutersInit() *gin.Engine{ link.PUT("/:id",m.Permission("console.link.update"),linkV,consoleLink.Update) link.DELETE("/:id",m.Permission("console.link.destroy"),consoleLink.Destroy) } - consoleAuth := auth.NewAuth() - au := c.Group("/register") + al := c.Group("/login") { - authRegisterV := validate.NewValidate().NewAuthLoginV.MyValidate() - au.GET("/",m.Permission("console.auth.index"),consoleAuth.Login) - au.POST("/",m.Permission("console.auth.index"),authRegisterV,consoleAuth.AuthLogin) + authLoginV := validate.NewValidate().NewAuthLoginV.MyValidate() + al.GET("/",m.Permission("console.login.index"),consoleAuth.Login) + al.POST("/",m.Permission("console.login.store"),authLoginV,consoleAuth.AuthLogin) + } + ar := c.Group("/register") + { + authRegisterV := validate.NewValidate().NewAuthRegister.MyValidate() + ar.GET("/",m.Permission("console.register.index"),consoleAuth.Register) + ar.POST("/",m.Permission("console.register.store"),authRegisterV,consoleAuth.AuthRegister) } //p.Use() //{ diff --git a/service/auth.go b/service/auth.go new file mode 100644 index 0000000..e77fc6c --- /dev/null +++ b/service/auth.go @@ -0,0 +1,50 @@ +/** + * Created by GoLand. + * User: xzghua@gmail.com + * Date: 2019-05-11 + * Time: 00:17 + */ +package service + +import ( + "fmt" + "github.com/izghua/go-blog/common" + "github.com/izghua/go-blog/conf" + "github.com/izghua/go-blog/entity" + "github.com/izghua/zgh" + "golang.org/x/crypto/bcrypt" +) + +func GetUserByEmail(email string) (user *entity.ZUsers,err error) { + user = new(entity.ZUsers) + _,err = conf.SqlServer.Where("email = ?",email).Get(user) + return +} + +func GetUserCnt() (cnt int64,err error) { + user := new(entity.ZUsers) + cnt,err = conf.SqlServer.Count(user) + return +} + +func UserStore(ar common.AuthRegister) (user *entity.ZUsers, err error) { + password := []byte(ar.Password) + hashedPassword, err := bcrypt.GenerateFromPassword(password, bcrypt.DefaultCost) + if err != nil { + zgh.ZLog().Error("message","service.UserStore","error",err.Error()) + return + } + userInsert := entity.ZUsers{ + Name: ar.UserName, + Email:ar.Email, + Password: string(hashedPassword), + Status: 1, + } + _,err = conf.SqlServer.Insert(&userInsert) + if err != nil { + zgh.ZLog().Error("message","service.UserStore","error",err.Error()) + return + } + fmt.Println(userInsert.Id) + return +} \ No newline at end of file diff --git a/validate/auth_login.go b/validate/auth_login.go index f6273b7..f052b37 100644 --- a/validate/auth_login.go +++ b/validate/auth_login.go @@ -19,13 +19,13 @@ type AuthLoginV struct { func (av *AuthLoginV) MyValidate() gin.HandlerFunc { return func(c *gin.Context) { appG := api.Gin{C: c} - var json common.AuthRegister + var json common.AuthLogin if err := c.ShouldBindJSON(&json); err != nil { appG.Response(http.StatusOK, 400001000, nil) return } - reqValidate := &AuthRegister{ + reqValidate := &AuthLogin{ Email:json.Email, Password:json.Password, Captcha:json.Captcha, @@ -39,14 +39,14 @@ func (av *AuthLoginV) MyValidate() gin.HandlerFunc { } } -type AuthRegister struct { +type AuthLogin struct { Email string `valid:"Required;Email"` Password string `valid:"Required;MaxSize(30)"` Captcha string `valid:"Required;MaxSize(5)"` CaptchaKey string `valid:"Required;MaxSize(30)"` } -func (av *AuthRegister) Message() map[string]int { +func (av *AuthLogin) Message() map[string]int { return map[string]int{ "Email.Required":407000000, "Email.Email":407000001, diff --git a/validate/auth_register.go b/validate/auth_register.go new file mode 100644 index 0000000..1090db5 --- /dev/null +++ b/validate/auth_register.go @@ -0,0 +1,56 @@ +/** + * Created by GoLand. + * User: xzghua@gmail.com + * Date: 2019-05-11 + * Time: 00:43 + */ +package validate + +import ( + "github.com/gin-gonic/gin" + "github.com/izghua/go-blog/common" + "github.com/izghua/zgh/gin/api" + "net/http" +) + +type AuthRegisterV struct { +} + +func (av *AuthRegisterV) MyValidate() gin.HandlerFunc { + return func(c *gin.Context) { + appG := api.Gin{C: c} + var json common.AuthRegister + if err := c.ShouldBindJSON(&json); err != nil { + appG.Response(http.StatusOK, 400001000, nil) + return + } + + reqValidate := &AuthRegister{ + Email:json.Email, + Password:json.Password, + UserName: json.UserName, + } + if b := appG.Validate(reqValidate); !b { + return + } + c.Set("json",json) + c.Next() + } +} + +type AuthRegister struct { + UserName string `valid:"Required;MaxSize(30)"` + Email string `valid:"Required;Email"` + Password string `valid:"Required;MaxSize(30)"` +} + +func (av *AuthRegister) Message() map[string]int { + return map[string]int{ + "Email.Required":407000000, + "Email.Email":407000001, + "Password.Required":407000002, + "Password.MaxSize":407000003, + "UserName.Required":407000012, + "UserName.MaxSize":407000013, + } +} diff --git a/validate/v.go b/validate/v.go index 09958f3..92e743b 100644 --- a/validate/v.go +++ b/validate/v.go @@ -19,15 +19,17 @@ type SomeValidate struct { NewSystemV V NewLinkV V NewAuthLoginV V + NewAuthRegister V } func NewValidate() *SomeValidate { return &SomeValidate{ - NewPostV: &PostStoreV{}, - NewCateV: &CateStoreV{}, - NewTagV: &TagStoreV{}, - NewSystemV: &SystemUpdateV{}, - NewLinkV: &LinkStoreV{}, - NewAuthLoginV: &AuthLoginV{}, + NewPostV: &PostStoreV{}, + NewCateV: &CateStoreV{}, + NewTagV: &TagStoreV{}, + NewSystemV: &SystemUpdateV{}, + NewLinkV: &LinkStoreV{}, + NewAuthLoginV: &AuthLoginV{}, + NewAuthRegister: &AuthRegisterV{}, } }